{% extends "base.html" %}

{% block title %}系统配置管理 - LandPPT{% endblock %}

{% block content %}
<div class="ai-config-page">
    <div class="page-hero">
        <div>
            <p class="hero-eyebrow">配置中心</p>
            <h2 class="page-title">系统配置管理</h2>
            <p class="page-subtitle">
                配置和管理 LandPPT 的所有系统参数，包括 AI 提供者、生成参数、应用配置等。
            </p>
            <!-- <div class="hero-meta">
            <span class="pill pill--solid">当前提供者：{{ current_provider }}</span>
            <span class="pill">可用提供者：{{ available_providers | length }} 个</span>
        </div> -->
        </div>
        <!-- <div class="hero-actions">
        <button onclick="testCurrentProvider()" class="btn btn-primary">
            测试当前提供者
        </button>
        <button onclick="refreshProviders()" class="btn btn-secondary">
            刷新状态
        </button>
    </div> -->
    </div>

    <!-- 配置导航标签 -->
    <div style="margin-bottom: 30px;">
        <div class="config-tabs" style="display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;">
            <button class="tab-btn active" onclick="switchTab('ai-providers')" data-tab="ai-providers">
                AI 提供者
            </button>
            <button class="tab-btn" onclick="switchTab('generation-params')" data-tab="generation-params">
                生成参数
            </button>
            <button class="tab-btn" onclick="switchTab('app-config')" data-tab="app-config">
                应用配置
            </button>
            <button class="tab-btn" onclick="switchTab('image-service')" data-tab="image-service">
                图片服务
            </button>
        </div>
    </div>

    <!-- AI 提供者配置标签页 -->
    <div id="ai-providers" class="tab-content active">
        <div class="grid">
            <div class="card">
                <h3 class="section-heading">当前状态</h3>

                <div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
                    <p style="margin-bottom: 10px;">
                        <strong>当前提供者:</strong>
                        <span class="pill pill--solid">
                            {{ current_provider }}
                        </span>
                    </p>
                    <p style="margin-bottom: 10px;">
                        <strong>可用提供者:</strong> {{ available_providers | length }} 个
                    </p>
                    <p>
                        <strong>状态:</strong>
                        {% if current_provider in available_providers %}
                        <span class="status-label status-label--ok">正常运行</span>
                        {% else %}
                        <span class="status-label status-label--err">配置错误</span>
                        {% endif %}
                    </p>
                </div>
            </div>


        </div>

        <div style="margin-top: 30px;">
            <h3 class="section-heading" style="text-align: center;">AI 提供者详情配置</h3>

            <div class="grid">
                {% for provider in ["openai", "anthropic", "google", "azure_openai", "ollama", "302ai"] %}
                <div class="card provider-config-card" data-provider="{{ provider }}">
                    <div
                        style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
                        <h4 style="color: #111111; margin: 0;">
                            {% if provider == "openai" %}
                            OpenAI
                            {% elif provider == "anthropic" %}
                            Anthropic Claude
                            {% elif provider == "google" %}
                            Google Gemini
                            {% elif provider == "azure_openai" %}
                            Azure OpenAI
                            {% elif provider == "ollama" %}
                            Ollama (本地)
                            {% elif provider == "302ai" %}
                            302.AI
                            {% endif %}
                        </h4>

                        <div style="display: flex; gap: 10px; align-items: center;">
                            {% if provider_status[provider] %}
                            <span
                                style="background: #0f0f0f; color: #f8f8f8; padding: 4px 12px; border-radius: 20px; font-size: 0.8em; border: 1px solid #1f1f1f;">
                                可用
                            </span>
                            {% else %}
                            <span
                                style="background: #e0e0e0; color: #111111; padding: 4px 12px; border-radius: 20px; font-size: 0.8em; border: 1px solid #c2c2c2;">
                                不可用
                            </span>
                            {% endif %}

                            <div class="custom-radio">
                                <input type="radio" name="default_provider" value="{{ provider }}"
                                    id="provider_{{ provider }}" {% if current_provider==provider %}checked{% endif %}
                                    onchange="setDefaultProvider('{{ provider }}')">
                                <label for="provider_{{ provider }}" class="radio-label">默认</label>
                            </div>
                        </div>
                    </div>

                    <!-- 提供者配置表单 -->
                    <div class="provider-config-form">
                        {% if provider == "openai" %}
                        <div class="form-group">
                            <label>API Key:</label>
                            <input type="password" name="openai_api_key" placeholder="sk-..."
                                value="{{ current_config.get('openai_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em;">
                        </div>
                        <div class="form-group">
                            <label>Base URL:</label>
                            <input type="text" name="openai_base_url"
                                value="{{ current_config.get('openai_base_url', '') }}"
                                placeholder="{{ current_config.get('openai_base_url', 'https://api.openai.com/v1') }}">
                        </div>
                        <div class="form-group">
                            <label>默认模型:</label>
                            <div class="model-input-container">
                                <div class="searchable-select-container" id="openai_model_container"
                                    style="display: none;">
                                    <input type="text" class="searchable-select-input" id="openai_model_search"
                                        placeholder="搜索模型...">
                                    <div class="searchable-select-dropdown" id="openai_model_dropdown">
                                        <div class="searchable-select-option" data-value="">选择模型...</div>
                                    </div>
                                </div>
                                <input type="text" name="openai_model" id="openai_model_input" class="model-input"
                                    value="{{ current_config.get('openai_model', '') }}"
                                    placeholder="{{ current_config.get('openai_model', 'gpt-4o') }}">
                                <button type="button" onclick="fetchAndShowModels()" id="openai_model_fetch_btn"
                                    class="model-fetch-btn" title="获取可用模型列表">
                                    列表
                                </button>
                            </div>
                        </div>
                        {% elif provider == "anthropic" %}
                        <div class="form-group">
                            <label>API Key:</label>
                            <input type="password" name="anthropic_api_key" placeholder="sk-ant-..."
                                value="{{ current_config.get('anthropic_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em;">
                        </div>
                        <div class="form-group">
                            <label>默认模型:</label>
                            <input type="text" name="anthropic_model"
                                value="{{ current_config.get('anthropic_model', '') }}"
                                placeholder="{{ current_config.get('anthropic_model', 'claude-3-5-sonnet-20241022') }}">
                        </div>
                        {% elif provider == "google" %}
                        <div class="form-group">
                            <label>API Key:</label>
                            <input type="password" name="google_api_key" placeholder="your-google-api-key"
                                value="{{ current_config.get('google_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em;">
                        </div>
                        <div class="form-group">
                            <label>Base URL:</label>
                            <input type="text" name="google_base_url"
                                value="{{ current_config.get('google_base_url', '') }}"
                                placeholder="{{ current_config.get('google_base_url', 'https://generativelanguage.googleapis.com') }}">
                        </div>
                        <div class="form-group">
                            <label>默认模型:</label>
                            <input type="text" name="google_model" value="{{ current_config.get('google_model', '') }}"
                                placeholder="{{ current_config.get('google_model', 'gemini-2.5-flash') }}">
                        </div>
                        {% elif provider == "azure_openai" %}
                        <div class="form-group">
                            <label>API Key:</label>
                            <input type="password" name="azure_openai_api_key" placeholder="your-azure-key"
                                value="{{ current_config.get('azure_openai_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em;">
                        </div>
                        <div class="form-group">
                            <label>Endpoint:</label>
                            <input type="text" name="azure_openai_endpoint"
                                value="{{ current_config.get('azure_openai_endpoint', '') }}"
                                placeholder="https://your-resource.openai.azure.com/">
                        </div>
                        <div class="form-group">
                            <label>Deployment Name:</label>
                            <input type="text" name="azure_openai_deployment_name"
                                value="{{ current_config.get('azure_openai_deployment_name', '') }}"
                                placeholder="your-deployment-name">
                        </div>
                        <div class="form-group">
                            <label>API Version:</label>
                            <input type="text" name="azure_openai_api_version"
                                value="{{ current_config.get('azure_openai_api_version', '') }}"
                                placeholder="2024-02-15-preview">
                        </div>
                        {% elif provider == "ollama" %}
                        <div class="form-group">
                            <label>Base URL:</label>
                            <input type="text" name="ollama_base_url"
                                value="{{ current_config.get('ollama_base_url', '') }}"
                                placeholder="{{ current_config.get('ollama_base_url', 'http://localhost:11434') }}">
                        </div>
                        <div class="form-group">
                            <label>默认模型:</label>
                            <input type="text" name="ollama_model" value="{{ current_config.get('ollama_model', '') }}"
                                placeholder="{{ current_config.get('ollama_model', 'llama2, mistral, codellama...') }}">
                        </div>
                        {% elif provider == "302ai" %}
                        <div class="form-group">
                            <label>API Key:</label>
                            <input type="password" name="302ai_api_key" placeholder="sk-..."
                                value="{{ current_config.get('302ai_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em;">
                            <small style="color: #2b2b2b;"><a href="https://share.302.ai/5ml9vD" target="_blank"
                                    style="color: #2b2b2b; text-decoration: underline;">点击获取</a></small>
                        </div>
                        <input type="hidden" name="302ai_base_url" value="https://api.302.ai/v1">
                        <div class="form-group">
                            <label>默认模型:</label>
                            <div class="model-input-container">
                                <div class="searchable-select-container" id="302ai_model_container"
                                    style="display: none;">
                                    <input type="text" class="searchable-select-input" id="302ai_model_search"
                                        placeholder="搜索模型...">
                                    <div class="searchable-select-dropdown" id="302ai_model_dropdown">
                                        <div class="searchable-select-option" data-value="">选择模型...</div>
                                    </div>
                                </div>
                                <input type="text" name="302ai_model" id="302ai_model_input" class="model-input"
                                    value="{{ current_config.get('302ai_model', '') }}"
                                    placeholder="{{ current_config.get('302ai_model', 'gpt-4o') }}">
                                <button type="button" onclick="fetch302AIModels()" id="302ai_model_fetch_btn"
                                    class="model-fetch-btn" title="获取可用模型列表">
                                    列表
                                </button>
                            </div>
                        </div>
                        {% endif %}
                    </div>

                    <div style="text-align: center; margin-top: 15px;">
                        <button onclick="testProvider('{{ provider }}')" class="btn btn-primary"
                            style="margin-right: 10px;">
                            测试
                        </button>
                        <button onclick="saveProviderConfig('{{ provider }}')" class="btn btn-success">
                            保存配置
                        </button>
                    </div>
                </div>
                {% endfor %}
            </div>
        </div>

        <!-- 模型任务配置-->
        <div id="model-roles">
            <div style="margin: 0 auto;">
                <div class="card" style="margin-bottom: 20px;">
                    <div
                        style="display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;">
                        <div>
                            <h3 class="section-heading" style="margin-bottom: 6px;">模型任务配置</h3>
                            <p style="color: #7f8c8d; margin: 0;">该区域为高级设置，可为不同功能指定专用提供者和模型，未设置时将继承默认配置。</p>
                        </div>
                        <button type="button" id="model-role-toggle-btn" class="btn btn-secondary"
                            style="min-width: 140px;" onclick="toggleModelRoleSettings()">
                            展开设置
                        </button>
                    </div>
                </div>
                <div id="model-role-settings" style="display: none;">
                    <div class="grid" style="gap: 20px;">
                        {% set model_roles = [
                        {'label': '默认模型', 'provider_field': 'default_model_provider', 'model_field':
                        'default_model_name'},
                        {'label': '大纲生成 / 要点增强', 'provider_field': 'outline_model_provider', 'model_field':
                        'outline_model_name'},
                        {'label': '创意指导', 'provider_field': 'creative_model_provider', 'model_field':
                        'creative_model_name'},
                        {'label': '配图与提示词', 'provider_field': 'image_prompt_model_provider', 'model_field':
                        'image_prompt_model_name'},
                        {'label': '幻灯片生成', 'provider_field': 'slide_generation_model_provider', 'model_field':
                        'slide_generation_model_name'},
                        {'label': '演讲稿生成', 'provider_field': 'speech_script_model_provider', 'model_field':
                        'speech_script_model_name'},
                        {'label': 'AI编辑助手', 'provider_field': 'editor_assistant_model_provider', 'model_field':
                        'editor_assistant_model_name'},
                        {'label': 'AI模板生成', 'provider_field': 'template_generation_model_provider', 'model_field':
                        'template_generation_model_name'},
                        {'label': '多模态视觉分析', 'provider_field': 'vision_analysis_model_provider', 'model_field':
                        'vision_analysis_model_name'}
                        ] %}
                        {% for role in model_roles %}
                        <div class="card" data-role-model-field="{{ role.model_field }}">
                            <h4 style="color: #111111; margin-bottom: 15px;">{{ role.label }}</h4>
                            <div class="form-group" style="margin-bottom: 15px;">
                                <label>首选提供者</label>
                                <select name="{{ role.provider_field }}" class="model-role-provider"
                                    data-model-field="{{ role.model_field }}"
                                    style="width: 100%; padding: 10px; border: 1px solid #dcdcdc; border-radius: 6px;">
                                    <option value="">使用默认提供者</option>
                                    {% for provider in available_providers %}
                                    <option value="{{ provider }}" {% if
                                        current_config.get(role.provider_field)==provider %}selected{% endif %}>{{
                                        provider }}</option>
                                    {% endfor %}
                                </select>
                            </div>
                            <div class="form-group" style="margin-bottom: 15px;">
                                <label>模型</label>
                                <div class="model-input-container">
                                    <div class="searchable-select-container role-model-searchable-select"
                                        data-model-field="{{ role.model_field }}" style="display: none;">
                                        <input type="text" class="searchable-select-input role-model-search"
                                            data-model-field="{{ role.model_field }}" placeholder="搜索模型...">
                                        <div class="searchable-select-dropdown role-model-dropdown"
                                            data-model-field="{{ role.model_field }}">
                                            <div class="searchable-select-option" data-value="">选择模型...</div>
                                        </div>
                                    </div>
                                    <input type="text" name="{{ role.model_field }}"
                                        class="model-input role-model-input" data-model-field="{{ role.model_field }}"
                                        value="{{ current_config.get(role.model_field, '') }}"
                                        placeholder="留空时使用提供者默认模型">
                                    <button type="button" class="model-fetch-btn openai-fetch-btn"
                                        data-model-field="{{ role.model_field }}" onclick="fetchRoleOpenAIModels(this)"
                                        style="display: none;" title="获取可用模型列表">
                                        列表
                                    </button>
                                </div>
                                <small style="color: #7f8c8d;">留空表示继承该提供者默认模型</small>
                            </div>
                        </div>
                        {% endfor %}
                    </div>
                    <div style="text-align: center; margin-top: 30px;">
                        <button onclick="saveModelRoleConfig()" class="btn btn-success"
                            style="padding: 12px 30px; font-weight: 600; font-size: 1.05em;">保存模型任务配置</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div id="generation-params" class="tab-content" style="display: none;">
        <div class="card">
            <h3 class="section-heading" style="margin-bottom: 30px; text-align: center;">AI 生成参数配置</h3>

            <!-- 主要配置区域 -->
            <div style="display: flex; flex-direction: column; gap: 30px;">

                <!-- AI 生成参数 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 style="color: #111111; margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        AI 生成参数
                    </h4>
                    <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                最大令牌数 (MAX_TOKENS)
                            </label>
                            <div class="input-with-range">
                                <input type="number" name="max_tokens" min="100" max="1000000"
                                    value="{{ current_config.get('max_tokens', '') }}"
                                    placeholder="{{ current_config.get('max_tokens', '8192') }}"
                                    style="margin-bottom: 8px;">
                                <input type="range" min="100" max="1000000" step="100"
                                    value="{{ current_config.get('max_tokens', '8192') }}"
                                    oninput="this.previousElementSibling.value = this.value"
                                    style="width: 100%; accent-color: #0f0f0f;">
                            </div>
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                控制生成内容的最大长度。较大的值允许生成更长的内容，但会消耗更多资源。
                            </small>
                        </div>

                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                温度 (TEMPERATURE)
                            </label>
                            <div class="input-with-range">
                                <input type="number" name="temperature" min="0" max="2" step="0.1"
                                    value="{{ current_config.get('temperature', '') }}"
                                    placeholder="{{ current_config.get('temperature', '0.7') }}"
                                    style="margin-bottom: 8px;">
                                <input type="range" min="0" max="2" step="0.1"
                                    value="{{ current_config.get('temperature', '0.7') }}"
                                    oninput="this.previousElementSibling.value = this.value"
                                    style="width: 100%; accent-color: #0f0f0f;">
                            </div>
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                控制生成内容的创造性。0 = 确定性输出，1 = 平衡，2 = 高创造性。
                            </small>
                        </div>

                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                Top-P (TOP_P)
                            </label>
                            <div class="input-with-range">
                                <input type="number" name="top_p" min="0" max="1" step="0.1"
                                    value="{{ current_config.get('top_p', '') }}"
                                    placeholder="{{ current_config.get('top_p', '1.0') }}" style="margin-bottom: 8px;">
                                <input type="range" min="0" max="1" step="0.1"
                                    value="{{ current_config.get('top_p', '1.0') }}"
                                    oninput="this.previousElementSibling.value = this.value"
                                    style="width: 100%; accent-color: #0f0f0f;">
                            </div>
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                核采样参数，控制词汇选择范围。较低的值使输出更集中，较高的值增加多样性。
                            </small>
                        </div>
                    </div>
                </div>

                <!-- 批量生成PPT配置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 style="color: #111111; margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        批量生成PPT
                    </h4>

                    <div style="margin-bottom: 20px;">
                        <label class="toggle-label" style="cursor: pointer; user-select: none;">
                            <div class="toggle-switch">
                                <input type="checkbox" name="enable_parallel_generation" id="enable_parallel_generation"
                                    onchange="toggleParallelGenerationOptions()">
                                <span class="toggle-slider"></span>
                            </div>
                            <div>
                                <div style="font-weight: 600; color: #495057; margin-bottom: 4px;">启用批量生成</div>
                                <small style="color: #6c757d; font-weight: 400;">启用后可以同时生成多个幻灯片，显著提高生成速度</small>
                            </div>
                        </label>
                    </div>

                    <div class="form-group" style="margin-bottom: 20px;">
                        <label class="toggle-label"
                            style="cursor: pointer; user-select: none; display: flex; align-items: center; gap: 12px;">
                            <div class="toggle-switch">
                                <input type="checkbox" name="enable_auto_layout_repair" id="enable_auto_layout_repair">
                                <span class="toggle-slider"></span>
                            </div>
                            <div>
                                <div style="font-weight: 600; color: #495057;">开启自动修复排版</div>
                                <div style="font-size: 0.85em; color: #6c757d;">使用专用多模态模型检查页面视觉效果，识别遮挡/错位并输出修复后的 HTML
                                </div>
                            </div>
                        </label>
                    </div>

                    <div id="parallel-generation-options"
                        style="display: none; padding: 20px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #111111;">
                        <div class="form-group" style="margin-bottom: 0;">
                            <label for="parallel_slides_count"
                                style="font-weight: 600; color: #495057; display: block; margin-bottom: 12px;">
                                批量生成页数
                            </label>
                            <div style="display: flex; align-items: center; gap: 15px; margin-bottom: 12px;">
                                <input type="number" name="parallel_slides_count" id="parallel_slides_count"
                                    value="{{ current_config.get('parallel_slides_count', '3') }}" min="1" max="10"
                                    style="flex: 0 0 100px; padding: 10px 12px; border: 2px solid #dcdcdc; border-radius: 8px; font-size: 1em;"
                                    oninput="updateParallelSlidesDisplay(this.value); document.getElementById('parallel_slides_range').value = this.value;">
                                <input type="range" id="parallel_slides_range" min="1" max="10"
                                    value="{{ current_config.get('parallel_slides_count', '3') }}"
                                    style="flex: 1; accent-color: #0f0f0f;"
                                    oninput="document.getElementById('parallel_slides_count').value = this.value; updateParallelSlidesDisplay(this.value);">
                                <span id="parallel_slides_display"
                                    style="flex: 0 0 80px; text-align: center; font-weight: 600; color: #111111; font-size: 1.1em; padding: 8px 12px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                                    {{ current_config.get('parallel_slides_count', '3') }} 页
                                </span>
                            </div>
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                <strong>提示：</strong>数值越大，生成速度越快，但对AI服务的并发请求压力也越大。<br>
                                推荐值：<span style="color: #111111; font-weight: 500;">3-5页</span>（平衡速度与稳定性）
                            </small>
                        </div>
                    </div>

                    <div
                        style="margin-top: 15px; padding: 12px 16px; background: rgba(0, 0, 0, 0.06); border-radius: 8px; border-left: 4px solid #111111;">
                        <p style="margin: 0; font-size: 0.9em; color: #495057; line-height: 1.6;">
                            <strong>注意事项：</strong><br>
                            • 启用批量生成可能会增加AI API的调用频率和费用<br>
                            • 部分AI提供商可能有并发请求限制，请根据实际情况调整<br>
                            • 如遇到频率限制错误，建议降低并行页数或关闭此功能
                        </p>
                    </div>
                </div>

                <!-- 研究功能配置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 class="section-heading"
                        style="margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        研究功能配置
                    </h4>

                    <!-- 研究提供商选择 -->
                    <div style="margin-bottom: 25px;">
                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                研究提供商 (RESEARCH_PROVIDER)
                            </label>
                            <select name="research_provider" style="margin-bottom: 8px;">
                                <option value="tavily">Tavily (推荐)</option>
                                <option value="searxng">SearXNG</option>
                                <option value="both">两者都使用</option>
                            </select>
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                选择用于研究的搜索提供商。Tavily 提供更准确的结果，SearXNG 是开源选择。
                            </small>
                        </div>
                    </div>

                    <!-- API 密钥配置 -->
                    <div
                        style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-bottom: 25px;">
                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                Tavily API Key
                            </label>
                            <input type="password" name="tavily_api_key" placeholder="tvly-..."
                                value="{{ current_config.get('tavily_api_key', '') }}"
                                style="font-family: monospace; font-size: 0.9em; margin-bottom: 8px;">
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                用于深度研究功能的API密钥，可在 <a href="https://tavily.com" target="_blank"
                                    style="color: #111111; text-decoration: underline;">Tavily官网</a> 获取
                            </small>
                        </div>

                        <div class="form-group">
                            <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                SearXNG 主机地址
                            </label>
                            <input type="url" name="searxng_host" placeholder="http://localhost:8888"
                                value="{{ current_config.get('searxng_host', '') }}"
                                style="font-family: monospace; font-size: 0.9em; margin-bottom: 8px;">
                            <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                SearXNG 实例的完整URL地址，用于开源搜索引擎研究功能
                            </small>
                        </div>
                    </div>

                    <!-- 高级选项 -->
                    <div
                        style="background: #f8f9fa; padding: 20px; border-radius: 8px; border-left: 4px solid #111111;">
                        <h5
                            style="color: #111111; margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            高级选项
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
                            <div class="form-group">
                                <label class="toggle-label">
                                    <div class="toggle-switch">
                                        <input type="checkbox" name="research_enable_content_extraction">
                                        <span class="toggle-slider"></span>
                                    </div>
                                    <div>
                                        <div style="font-weight: 600; color: #495057; margin-bottom: 4px;">启用深度内容提取
                                        </div>
                                        <small
                                            style="color: #6c757d; font-weight: 400;">从搜索结果页面提取完整内容进行深度分析，提高研究质量</small>
                                    </div>
                                </label>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                                    最大内容长度
                                </label>
                                <div class="input-with-range">
                                    <input type="number" name="research_max_content_length" min="1000" max="20000"
                                        value="{{ current_config.get('research_max_content_length', '') }}"
                                        placeholder="{{ current_config.get('research_max_content_length', '5000') }}"
                                        style="margin-bottom: 8px;">
                                    <input type="range" min="1000" max="20000" step="500"
                                        value="{{ current_config.get('research_max_content_length', '5000') }}"
                                        oninput="this.previousElementSibling.value = this.value"
                                        style="width: 100%; accent-color: #0f0f0f;">
                                </div>
                                <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                                    每个页面提取的最大字符数，较大的值提供更多信息但消耗更多资源
                                </small>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 其他配置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 class="section-heading"
                        style="margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        其他配置
                    </h4>
                    <div class="form-group">
                        <label style="font-weight: 600; color: #495057; margin-bottom: 8px; display: block;">
                            Apryse License Key (PPT导出)
                        </label>
                        <input type="password" name="apryse_license_key" placeholder="your-apryse-license-key"
                            value="{{ current_config.get('apryse_license_key', '') }}"
                            style="font-family: monospace; font-size: 0.9em; margin-bottom: 8px;">
                        <small style="color: #6c757d; font-size: 0.85em; line-height: 1.4;">
                            用于PPTX导出功能的Apryse SDK许可证密钥，可在 <a href="https://www.pdftron.com/" target="_blank"
                                style="color: #111111; text-decoration: underline;">Apryse官网</a> 获取
                        </small>
                    </div>
                </div>
            </div>

            <!-- 操作按钮 -->
            <div
                style="text-align: center; margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 12px; border: 1px solid #e9ecef;">
                <button onclick="saveGenerationParams()" class="btn btn-success"
                    style="padding: 12px 30px; font-weight: 600; font-size: 1.05em;">
                    保存生成参数
                </button>
            </div>
        </div>
    </div>



    <!-- 应用配置标签页 -->
    <div id="app-config" class="tab-content" style="display: none;">
        <div class="card">
            <h3 class="section-heading" style="margin-bottom: 20px;">应用配置</h3>

            <div class="grid">
                <div>
                    <h4 class="subheading">服务器配置</h4>

                    <div class="form-group">
                        <label>主机地址 (HOST):</label>
                        <input type="text" name="host" placeholder="0.0.0.0">
                    </div>

                    <div class="form-group">
                        <label>端口 (PORT):</label>
                        <input type="number" name="port" min="1" max="65535" placeholder="8000">
                    </div>

                    <div class="form-group">
                        <label>基础URL (BASE_URL):</label>
                        <input type="url" name="base_url" placeholder="http://localhost:8000">
                        <small style="color: #7f8c8d;">用于生成图片等资源的绝对URL，支持反向代理域名</small>
                    </div>

                    <div class="form-group">
                        <label style="display: flex; align-items: center; gap: 10px;">
                            <input type="checkbox" name="reload">
                            自动重载 (RELOAD)
                        </label>
                    </div>
                </div>

                <div>
                    <h4 class="subheading">安全配置</h4>

                    <div class="form-group">
                        <label>密钥 (SECRET_KEY):</label>
                        <input type="password" name="secret_key" placeholder="your-very-secure-secret-key"
                            style="font-family: monospace; font-size: 0.9em;">
                        <small style="color: #7f8c8d;">用于会话加密的密钥</small>
                    </div>

                    <div class="form-group">
                        <label>访问令牌过期时间 (ACCESS_TOKEN_EXPIRE_MINUTES):</label>
                        <input type="number" name="access_token_expire_minutes" min="0" max="525600" placeholder="30">
                        <small style="color: #7f8c8d;">单位：分钟，设置为 0 表示永不过期</small>
                    </div>
                </div>

                <div>
                    <h4 class="subheading">文件上传配置</h4>

                    <div class="form-group">
                        <label>最大文件大小 (MAX_FILE_SIZE):</label>
                        <input type="number" name="max_file_size" min="1048576" max="104857600" placeholder="10485760">
                        <small style="color: #7f8c8d;">单位：字节 (10MB = 10485760)</small>
                    </div>

                    <div class="form-group">
                        <label>上传目录 (UPLOAD_DIR):</label>
                        <input type="text" name="upload_dir" placeholder="uploads">
                    </div>

                    <div class="form-group">
                        <label>缓存TTL (CACHE_TTL):</label>
                        <input type="number" name="cache_ttl" min="60" max="86400" placeholder="3600">
                        <small style="color: #7f8c8d;">单位：秒 (1小时 = 3600)</small>
                    </div>
                </div>

                <div>
                    <h4 class="subheading">数据库配置</h4>

                    <div class="form-group">
                        <label>数据库URL (DATABASE_URL):</label>
                        <input type="text" name="database_url" placeholder="sqlite:///./landppt.db">
                        <small style="color: #7f8c8d;">支持SQLite、PostgreSQL、MySQL等</small>
                    </div>
                </div>
            </div>

            <div style="text-align: center; margin-top: 20px;">
                <button onclick="saveAppConfig()" class="btn btn-success" style="margin-right: 10px;">
                    保存应用配置
                </button>
            </div>
        </div>
    </div>

    <!-- 图片服务配置标签页 -->
    <div id="image-service" class="tab-content" style="display: none;">
        <div class="card">
            <h3 class="section-heading" style="margin-bottom: 20px;">图片服务配置</h3>

            <!-- 服务状态显示 -->
            <div
                style="background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); padding: 20px; border-radius: 12px; margin-bottom: 25px; border: 1px solid #dee2e6;">
                <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px;">
                    <h4 class="subheading" style="margin: 0; font-size: 1.1em;">服务状态</h4>
                    <span id="image-service-status"
                        style="background: #0f0f0f; color: #f8f8f8; padding: 6px 14px; border-radius: 20px; font-size: 0.85em; font-weight: 500; border: 1px solid #1f1f1f;">
                        检查中...
                    </span>
                </div>
                <div style="color: #6c757d; font-size: 0.9em; line-height: 1.5;">
                    <strong>可用提供者:</strong> <span id="available-image-providers">检查中...</span>
                    <br>
                    <span style="color: #868e96;">图片服务为PPT生成提供视觉内容支持，包括AI图片生成、网络图片搜索和本地图片管理</span>
                </div>
            </div>

            <!-- 主要配置区域 -->
            <div style="display: flex; flex-direction: column; gap: 25px;">

                <!-- 基础设置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 class="subheading" style="margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        图片服务设置
                    </h4>

                    <div class="main-toggle-option">
                        <label class="toggle-label">
                            <div class="toggle-switch">
                                <input type="checkbox" name="enable_image_service"
                                    onchange="toggleImageServiceOptions()">
                                <span class="toggle-slider"></span>
                            </div>
                            <div>
                                <div style="font-size: 1.1em; font-weight: 600; color: #495057; margin-bottom: 4px;">
                                    启用图片生成服务</div>
                                <small style="color: #6c757d; font-weight: 400;">在PPT生成时自动添加相关图片，提升视觉效果</small>
                            </div>
                        </label>
                    </div>

                    <div id="image-service-options" style="display: none;">
                        <div
                            style="background: #f8f8f8; padding: 20px; border-radius: 8px; border-left: 4px solid #111111;">
                            <h5 style="color: #495057; margin-bottom: 15px; font-weight: 600;">图片获取方式 (可多选)</h5>
                            <div style="display: grid; gap: 12px;">
                                <label
                                    style="display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: white; border: 2px solid #e9ecef; border-radius: 8px; cursor: pointer; transition: all 0.2s;"
                                    onclick="toggleImageSourceConfig()">
                                    <input type="checkbox" name="enable_local_images" value="true"
                                        style="transform: scale(1.1);">
                                    <div style="flex: 1;">
                                        <div style="font-weight: 500; color: #495057;">本地图床</div>
                                        <small style="color: #6c757d;">从本地图片库中智能选择合适的图片</small>
                                    </div>
                                </label>
                                <label
                                    style="display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: white; border: 2px solid #e9ecef; border-radius: 8px; cursor: pointer; transition: all 0.2s;"
                                    onclick="toggleImageSourceConfig()">
                                    <input type="checkbox" name="enable_network_search" value="true"
                                        style="transform: scale(1.1);">
                                    <div style="flex: 1;">
                                        <div style="font-weight: 500; color: #495057;">网络搜索</div>
                                        <small style="color: #6c757d;">通过Unsplash、Pixabay等API搜索高质量网络图片</small>
                                    </div>
                                </label>
                                <label
                                    style="display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: white; border: 2px solid #e9ecef; border-radius: 8px; cursor: pointer; transition: all 0.2s;"
                                    onclick="toggleImageSourceConfig()">
                                    <input type="checkbox" name="enable_ai_generation" value="true"
                                        style="transform: scale(1.1);">
                                    <div style="flex: 1;">
                                        <div style="font-weight: 500; color: #495057;">AI生成</div>
                                        <small style="color: #6c757d;">使用AI模型生成定制化创意图片</small>
                                    </div>
                                </label>
                            </div>
                            <div
                                style="margin-top: 15px; padding: 12px; background: #f1f1f1; border-radius: 6px; border-left: 3px solid #111111;">
                                <small
                                    style="color: #4b5563; font-weight: 500;">提示：可以同时启用多种方式，AI会根据页面内容智能选择最合适的图片来源</small>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- API密钥配置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 class="subheading" style="margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        API密钥配置
                    </h4>

                    <!-- AI图片生成服务 -->
                    <div style="margin-bottom: 30px;">
                        <h5 class="subheading"
                            style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            AI图片生成服务
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">DALL-E API Key (OpenAI):</label>
                                <input type="password" name="openai_api_key_image" placeholder="sk-..."
                                    value="{{ current_config.get('openai_api_key_image', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">用于DALL-E
                                    3图片生成，与文本生成共用OpenAI密钥</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">SiliconFlow API Key:</label>
                                <input type="password" name="siliconflow_api_key" placeholder="your-siliconflow-api-key"
                                    value="{{ current_config.get('siliconflow_api_key', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">用于SiliconFlow
                                    Kolors图片生成</small>
                            </div>
                        </div>
                    </div>

                    <!-- Gemini图片生成服务 -->
                    <div style="margin-bottom: 30px;">
                        <h5 class="subheading"
                            style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            Gemini 图片生成 (Google)
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">Gemini 图片生成 API Key:</label>
                                <input type="password" name="gemini_image_api_key" placeholder="your-google-api-key"
                                    value="{{ current_config.get('gemini_image_api_key', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">用于Gemini图片生成的独立API密钥</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">API Base URL:</label>
                                <input type="text" name="gemini_image_api_base"
                                    placeholder="https://generativelanguage.googleapis.com/v1beta"
                                    value="{{ current_config.get('gemini_image_api_base', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">Gemini
                                    API端点，支持自定义代理</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">模型:</label>
                                <input type="text" name="gemini_image_model"
                                    placeholder="gemini-2.0-flash-exp-image-generation"
                                    value="{{ current_config.get('gemini_image_model', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">Gemini图片生成模型名称</small>
                            </div>
                        </div>
                    </div>

                    <!-- OpenAI图片生成服务（自定义端点） -->
                    <div style="margin-bottom: 30px;">
                        <h5 class="subheading"
                            style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            OpenAI 图片生成 (支持自定义端点)
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">OpenAI 图片生成 API Key:</label>
                                <input type="password" name="openai_image_api_key" placeholder="sk-..."
                                    value="{{ current_config.get('openai_image_api_key', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">用于OpenAI图片生成的独立API密钥</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">API Base URL:</label>
                                <input type="text" name="openai_image_api_base" placeholder="https://api.openai.com/v1"
                                    value="{{ current_config.get('openai_image_api_base', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">支持自定义API端点，如302.AI等兼容服务</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">模型:</label>
                                <input type="text" name="openai_image_model" placeholder="gpt-image-1"
                                    value="{{ current_config.get('openai_image_model', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">图片生成模型：gpt-image-1,
                                    dall-e-3, dall-e-2</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">图片质量:</label>
                                <select name="openai_image_quality" style="margin-top: 5px;">
                                    <option value="auto" {% if current_config.get('openai_image_quality')=='auto'
                                        %}selected{% endif %}>自动 (auto)</option>
                                    <option value="low" {% if current_config.get('openai_image_quality')=='low'
                                        %}selected{% endif %}>低 (low)</option>
                                    <option value="medium" {% if current_config.get('openai_image_quality')=='medium'
                                        %}selected{% endif %}>中 (medium)</option>
                                    <option value="high" {% if current_config.get('openai_image_quality')=='high'
                                        %}selected{% endif %}>高 (high)</option>
                                </select>
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">图片生成质量，更高质量需要更多时间和成本</small>
                            </div>
                        </div>
                    </div>

                    <!-- Pollinations免费服务 -->
                    <div style="margin-bottom: 30px;">
                        <h5 class="subheading"
                            style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            Pollinations (免费服务)
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">API Token (可选):</label>
                                <input type="password" name="pollinations_api_token"
                                    placeholder="your-pollinations-token"
                                    value="{{ current_config.get('pollinations_api_token', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">可选的API
                                    Token，用于移除logo和获得更高的使用限制</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">Referrer (可选):</label>
                                <input type="text" name="pollinations_referrer" placeholder="MyApp"
                                    value="{{ current_config.get('pollinations_referrer', '') }}"
                                    style="margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">推荐人标识符，用于认证和统计（可选）</small>
                            </div>
                        </div>
                        <div
                            style="margin-top: 15px; padding: 12px 16px; background: #f1f1f1; border: 1px solid #dcdcdc; border-radius: 8px; border-left: 4px solid #111111;">
                            <div
                                style="display: flex; align-items: center; gap: 8px; color: #111111; font-weight: 500;">
                                基础功能免费
                            </div>
                            <small
                                style="color: #4a4a4a; margin-top: 5px; display: block;">Pollinations提供免费的AI图片生成服务，Token可选用于高级功能</small>
                        </div>
                    </div>

                    <!-- 网络图片搜索服务 -->
                    <div>
                        <h5 class="subheading"
                            style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                            网络图片搜索服务
                        </h5>
                        <div
                            style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">Unsplash Access Key:</label>
                                <input type="password" name="unsplash_access_key" placeholder="your-unsplash-access-key"
                                    value="{{ current_config.get('unsplash_access_key', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">用于搜索Unsplash高质量摄影图片，支持多语言搜索</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">Pixabay API Key:</label>
                                <input type="password" name="pixabay_api_key" placeholder="your-pixabay-api-key"
                                    value="{{ current_config.get('pixabay_api_key', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small style="color: #6c757d; margin-top: 5px; display: block;">用于搜索免费图片和插图</small>
                            </div>

                            <div class="form-group">
                                <label style="font-weight: 500; color: #495057;">SearXNG Host:</label>
                                <input type="url" name="searxng_host" placeholder="http://localhost:8888"
                                    value="{{ current_config.get('searxng_host', '') }}"
                                    style="font-family: monospace; font-size: 0.9em; margin-top: 5px;">
                                <small
                                    style="color: #6c757d; margin-top: 5px; display: block;">SearXNG实例的主机地址，用于开源搜索引擎图片搜索</small>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 详细配置 -->
                <div
                    style="background: #fff; padding: 25px; border-radius: 12px; border: 1px solid #e9ecef; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
                    <h4 style="color: #111111; margin-bottom: 20px; display: flex; align-items: center; gap: 8px;">
                        <span>⚙️</span> 详细配置
                    </h4>

                    <!-- 配置选项容器 -->
                    <div style="display: flex; flex-direction: column; gap: 20px;">
                        <!-- 本地图床配置 -->
                        <div id="local-images-config"
                            style="display: none; padding: 20px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #111111;">
                            <h5 class="subheading"
                                style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                                本地图床配置
                            </h5>
                            <div
                                style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
                                <div class="form-group">
                                    <label class="toggle-label">
                                        <div class="toggle-switch">
                                            <input type="checkbox" name="local_images_smart_selection" checked>
                                            <span class="toggle-slider"></span>
                                        </div>
                                        <div>
                                            <div style="font-weight: 600; color: #495057; margin-bottom: 4px;">启用智能选择
                                            </div>
                                            <small
                                                style="color: #6c757d; font-weight: 400;">AI会根据内容智能匹配本地图片库中的图片</small>
                                        </div>
                                    </label>
                                </div>
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">每页最大本地图片数量:</label>
                                    <input type="number" name="max_local_images_per_slide" value="2" min="1" max="5"
                                        style="margin-top: 5px;">
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">限制每页从本地图床选择的图片数量</small>
                                </div>
                            </div>
                        </div>

                        <!-- 网络搜索配置 -->
                        <div id="network-search-config"
                            style="display: none; padding: 20px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #111111;">
                            <h5 class="subheading"
                                style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                                网络搜索配置
                            </h5>
                            <div
                                style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">默认网络搜索提供商:</label>
                                    <select name="default_network_search_provider" style="margin-top: 5px;">
                                        <option value="unsplash">Unsplash (高质量摄影图片)</option>
                                        <option value="pixabay" selected>Pixabay (免费图片和插图)</option>
                                        <option value="searxng">SearXNG (开源搜索引擎)</option>
                                    </select>
                                    <small style="color: #6c757d; margin-top: 5px; display: block;">选择优先使用的网络搜索源</small>
                                </div>
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">每页最大网络图片数量:</label>
                                    <input type="number" name="max_network_images_per_slide" value="2" min="1" max="5"
                                        style="margin-top: 5px;">
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">限制每页从网络搜索的图片数量</small>
                                </div>
                            </div>
                        </div>

                        <!-- AI生成配置 -->
                        <div id="ai-generation-config"
                            style="display: none; padding: 20px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #111111;">
                            <h5 class="subheading"
                                style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                                AI生成配置
                            </h5>
                            <div
                                style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px; margin-bottom: 20px;">
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">默认AI图片生成提供商:</label>
                                    <select name="default_ai_image_provider" onchange="toggleProviderSpecificConfig()"
                                        style="margin-top: 5px;">
                                        <option value="dalle" {% if
                                            current_config.get('default_ai_image_provider')=='dalle' %}selected{% endif
                                            %}>DALL-E 3 (OpenAI)</option>
                                        <option value="siliconflow" {% if
                                            current_config.get('default_ai_image_provider')=='siliconflow' %}selected{%
                                            endif %}>SiliconFlow (Kolors)</option>
                                        <option value="pollinations" {% if
                                            current_config.get('default_ai_image_provider')=='pollinations' %}selected{%
                                            endif %}>Pollinations (免费)</option>
                                        <option value="gemini" {% if
                                            current_config.get('default_ai_image_provider')=='gemini' %}selected{% endif
                                            %}>Gemini (Google)</option>
                                        <option value="openai_image" {% if
                                            current_config.get('default_ai_image_provider')=='openai_image' %}selected{%
                                            endif %}>OpenAI 图片生成</option>
                                    </select>
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">选择默认的AI图片生成服务</small>
                                </div>
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">每页最大AI生成图片数量:</label>
                                    <input type="number" name="max_ai_images_per_slide" value="1" min="1" max="3"
                                        style="margin-top: 5px;">
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">限制每页AI生成的图片数量</small>
                                </div>
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">图片生成质量:</label>
                                    <select name="ai_image_quality" style="margin-top: 5px;">
                                        <option value="standard">标准质量</option>
                                        <option value="hd">高清质量</option>
                                    </select>
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">更高质量的图片需要更多时间和成本</small>
                                </div>
                            </div>

                            <!-- Pollinations特定配置 -->
                            <div id="pollinations-specific-config"
                                style="display: none; padding: 20px; background: #f3f4f6; border-radius: 8px; border-left: 4px solid #111111;">
                                <h6 class="subheading"
                                    style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                                    Pollinations 配置
                                </h6>
                                <div
                                    style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px; margin-bottom: 15px;">
                                    <div class="form-group">
                                        <label style="font-weight: 500; color: #495057;">生成模型:</label>
                                        <select name="pollinations_model" style="margin-top: 5px;">
                                            <option value="flux">Flux (高质量，默认)</option>
                                            <option value="turbo">Turbo (快速生成)</option>
                                            <option value="gptimage">GPT Image (支持透明背景)</option>
                                        </select>
                                        <small
                                            style="color: #4a4a4a; margin-top: 5px; display: block;">选择Pollinations的图片生成模型</small>
                                    </div>
                                </div>
                                <div class="pollinations-options-grid">
                                    <div class="pollinations-option">
                                        <label class="pollinations-checkbox-label">
                                            <input type="checkbox" name="pollinations_enhance"
                                                class="pollinations-checkbox">
                                            <span class="pollinations-option-text">
                                                <strong>启用提示词增强</strong>
                                                <small>AI会自动优化和扩展您的提示词以获得更好的效果</small>
                                            </span>
                                        </label>
                                    </div>
                                    <div class="pollinations-option">
                                        <label class="pollinations-checkbox-label">
                                            <input type="checkbox" name="pollinations_safe"
                                                class="pollinations-checkbox">
                                            <span class="pollinations-option-text">
                                                <strong>启用安全过滤</strong>
                                                <small>启用严格的NSFW内容过滤</small>
                                            </span>
                                        </label>
                                    </div>
                                    <div class="pollinations-option">
                                        <label class="pollinations-checkbox-label">
                                            <input type="checkbox" name="pollinations_nologo"
                                                class="pollinations-checkbox">
                                            <span class="pollinations-option-text">
                                                <strong>移除Pollinations Logo</strong>
                                                <small>需要API Token或Referrer认证才能生效</small>
                                            </span>
                                        </label>
                                    </div>
                                    <div class="pollinations-option">
                                        <label class="pollinations-checkbox-label">
                                            <input type="checkbox" name="pollinations_private"
                                                class="pollinations-checkbox">
                                            <span class="pollinations-option-text">
                                                <strong>私有模式</strong>
                                                <small>生成的图片不会出现在公共feed中</small>
                                            </span>
                                        </label>
                                    </div>
                                    <div class="pollinations-option">
                                        <label class="pollinations-checkbox-label">
                                            <input type="checkbox" name="pollinations_transparent"
                                                class="pollinations-checkbox">
                                            <span class="pollinations-option-text">
                                                <strong>透明背景</strong>
                                                <small>生成透明背景图片（仅GPT Image模型支持）</small>
                                            </span>
                                        </label>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- 全局图片配置 -->
                        <div
                            style="padding: 20px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #111111;">
                            <h5 class="subheading"
                                style="margin-bottom: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px;">
                                全局图片配置
                            </h5>
                            <div
                                style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
                                <div class="form-group">
                                    <label style="font-weight: 500; color: #495057;">每页最大图片总数:</label>
                                    <input type="number" name="max_total_images_per_slide" value="3" min="1" max="8"
                                        style="margin-top: 5px;">
                                    <small
                                        style="color: #6c757d; margin-top: 5px; display: block;">限制每页图片的总数量，避免页面过于拥挤</small>
                                </div>
                                <div class="form-group">
                                    <label class="toggle-label">
                                        <div class="toggle-switch">
                                            <input type="checkbox" name="enable_smart_image_selection" checked>
                                            <span class="toggle-slider"></span>
                                        </div>
                                        <div>
                                            <div style="font-weight: 600; color: #495057; margin-bottom: 4px;">启用智能图片选择
                                            </div>
                                            <small
                                                style="color: #6c757d; font-weight: 400;">AI会根据页面内容和设计需求智能决定图片数量和来源</small>
                                        </div>
                                    </label>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 操作按钮 -->
                <div
                    style="text-align: center; margin-top: 25px; padding: 20px; background: #f8f9fa; border-radius: 12px; border: 1px solid #e9ecef;">
                    <button onclick="saveImageServiceConfig()" class="btn btn-success"
                        style="padding: 12px 30px; font-weight: 600; font-size: 1.05em;">
                        保存配置
                    </button>
                </div>
            </div>
        </div>
    </div>



    <!-- Test Results Modal -->
    <div id="testModal"
        style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000;">
        <div
            style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 40px; border-radius: 15px; width: 90%; max-width: 600px; max-height: 90vh; overflow-y: auto;">
            <h3 style="color: #111111; margin-bottom: 20px; text-align: center;">
                AI 提供者测试结果
            </h3>

            <div id="testResults" style="margin-bottom: 20px;">
                <!-- Test results will be inserted here -->
            </div>

            <div style="text-align: center;">
                <button onclick="closeTestModal()" class="btn btn-secondary">关闭</button>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_css %}
<style>
    /* 黑白主题基调 */
    .ai-config-page {
        --ai-surface: rgba(255, 255, 255, 0.94);
        --ai-surface-strong: rgba(255, 255, 255, 0.88);
        --ai-border: rgba(17, 17, 17, 0.12);
        --ai-contrast: #0f0f0f;
        --ai-muted: #5a5a5a;
        --ai-soft: #f6f6f6;
    }

    .ai-config-page .page-hero {
        background: var(--ai-surface);
        border: 1px solid var(--ai-border);
        box-shadow: 0 16px 32px rgba(15, 23, 42, 0.08);
        border-radius: var(--border-radius-lg, 16px);
        padding: 24px 28px;
        margin-bottom: 24px;
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: center;
        gap: 16px;
        position: relative;
        overflow: hidden;
    }

    .ai-config-page .page-hero::after {
        content: "";
        position: absolute;
        inset: -40px -80px auto auto;
        width: 240px;
        height: 240px;
        background: radial-gradient(circle, rgba(15, 15, 15, 0.08), transparent 55%);
        opacity: 0.6;
        pointer-events: none;
    }

    .ai-config-page .page-title {
        color: var(--ai-contrast);
        margin: 0 0 8px;
    }

    .ai-config-page .page-subtitle {
        color: var(--ai-muted);
        margin: 0;
        line-height: 1.6;
        max-width: 880px;
    }

    .ai-config-page .hero-eyebrow {
        color: var(--ai-muted);
        font-weight: 700;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        font-size: 0.8rem;
        margin: 0 0 6px;
    }

    .ai-config-page .hero-meta {
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
        margin-top: 12px;
    }

    .ai-config-page .hero-actions {
        display: flex;
        gap: 10px;
        flex-wrap: wrap;
        justify-content: flex-end;
    }

    .ai-config-page .hero-actions .btn {
        min-width: 140px;
    }

    @media (max-width: 900px) {
        .ai-config-page .page-hero {
            grid-template-columns: 1fr;
            align-items: flex-start;
        }

        .ai-config-page .hero-actions {
            justify-content: flex-start;
        }
    }

    .ai-config-page .card {
        background: var(--ai-surface);
        border: 1px solid var(--ai-border);
        box-shadow: 0 16px 36px rgba(15, 23, 42, 0.08);
    }

    .ai-config-page .section-heading,
    .ai-config-page .subheading {
        color: var(--ai-contrast);
    }

    .ai-config-page small {
        color: var(--ai-muted);
    }

    /* 配置标签页样式 */
    .config-tabs {
        border-bottom: 2px solid var(--ai-border);
        margin-bottom: 30px;
    }

    .tab-btn {
        background: var(--ai-surface-strong);
        backdrop-filter: blur(10px);
        border: 1px solid var(--ai-border);
        color: var(--ai-contrast);
        padding: 12px 24px;
        border-radius: 12px 12px 0 0;
        cursor: pointer;
        font-weight: 600;
        font-size: 0.95rem;
        transition: all 0.3s ease;
        margin-bottom: -2px;
        position: relative;
    }

    .tab-btn:hover {
        background: rgba(17, 17, 17, 0.06);
        transform: translateY(-2px);
    }

    .tab-btn.active {
        background: #0f0f0f;
        color: #f8f8f8;
        border-bottom: 2px solid transparent;
        transform: translateY(-2px);
        box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
    }

    .tab-content {
        animation: fadeIn 0.3s ease-in-out;
    }

    .tab-content.active {
        display: block !important;
    }

    @keyframes fadeIn {
        from {
            opacity: 0;
            transform: translateY(10px);
        }

        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    /* 提供者配置卡片样式 */
    .provider-config-card {
        transition: all 0.3s ease;
    }

    .provider-config-card:hover {
        transform: translateY(-5px);
        box-shadow: 0 15px 35px rgba(0, 0, 0, 0.16);
    }

    .provider-config-card,
    #model-role-settings .card {
        overflow: visible;
        z-index: 1;
    }

    .provider-config-card:focus-within,
    #model-role-settings .card:focus-within {
        z-index: 50;
    }

    .provider-config-card .model-input-container,
    #model-role-settings .model-input-container {
        position: relative;
        z-index: 1;
    }

    .provider-config-card .model-input-container:focus-within,
    .provider-config-card .searchable-select-container.open,
    #model-role-settings .model-input-container:focus-within,
    #model-role-settings .searchable-select-container.open {
        z-index: 60;
    }

    .provider-config-card .searchable-select-dropdown,
    #model-role-settings .searchable-select-dropdown {
        z-index: 2000;
    }

    .provider-config-card .searchable-select-container.open .searchable-select-dropdown,
    #model-role-settings .searchable-select-container.open .searchable-select-dropdown {
        z-index: 3000;
    }

    .provider-config-form .form-group {
        margin-bottom: 15px;
    }

    .provider-config-form .form-group label {
        font-size: 0.9rem;
        font-weight: 600;
        margin-bottom: 5px;
    }

    .provider-config-form .form-group input,
    .provider-config-form .form-group select {
        padding: 10px 15px;
        font-size: 0.9rem;
    }

    .provider-config-form .form-group small {
        display: block;
        margin-top: 5px;
        font-size: 0.8rem;
        line-height: 1.4;
    }



    /* 状态指示器 */
    .status-indicator {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        padding: 4px 12px;
        border-radius: 20px;
        font-size: 0.8em;
        font-weight: 600;
    }

    .status-available {
        background: linear-gradient(135deg, #0f0f0f 0%, #1f1f1f 100%);
        color: #f8f8f8;
        border: 1px solid #1f1f1f;
    }

    .status-unavailable {
        background: #e0e0e0;
        color: #111111;
        border: 1px solid #c4c4c4;
    }

    .status-label--ok {
        background: linear-gradient(135deg, #0f0f0f 0%, #1f1f1f 100%);
        color: #f8f8f8;
        border: 1px solid #1f1f1f;
    }

    .status-label--err {
        background: #e0e0e0;
        color: #111111;
        border: 1px solid #c4c4c4;
    }

    /* 现代化单选框样式 */
    .custom-radio {
        display: flex;
        align-items: center;
        gap: 10px;
        margin-left: 10px;
    }

    .custom-radio input[type="radio"] {
        appearance: none;
        -webkit-appearance: none;
        width: 22px;
        height: 22px;
        border: 2px solid #d3d3d3;
        border-radius: 50%;
        position: relative;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        background: white;
        flex-shrink: 0;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    }

    .custom-radio input[type="radio"]:hover {
        border-color: #0f0f0f;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        transform: translateY(-1px) scale(1.05);
    }

    .custom-radio input[type="radio"]:focus {
        outline: none;
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
    }

    .custom-radio input[type="radio"]:checked {
        border-color: #0f0f0f;
        background: linear-gradient(135deg, #0f0f0f 0%, #2a2a2a 100%);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
    }

    .custom-radio input[type="radio"]:checked::after {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background: white;
        opacity: 1;
        animation: radiomark 0.3s ease-in-out;
    }

    @keyframes radiomark {
        0% {
            opacity: 0;
            transform: translate(-50%, -50%) scale(0);
        }

        50% {
            opacity: 1;
            transform: translate(-50%, -50%) scale(1.3);
        }

        100% {
            opacity: 1;
            transform: translate(-50%, -50%) scale(1);
        }
    }

    .custom-radio .radio-label {
        font-size: 0.9em;
        color: #495057;
        font-weight: 600;
        cursor: pointer;
        transition: color 0.3s ease;
        user-select: none;
    }

    .custom-radio input[type="radio"]:checked+.radio-label {
        color: #0f0f0f;
    }

    /* 单选框禁用状态 */
    .custom-radio input[type="radio"]:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        background: #f8f9fa;
        border-color: #e9ecef;
    }

    .custom-radio input[type="radio"]:disabled:hover {
        transform: none;
        box-shadow: none;
    }

    .custom-radio input[type="radio"]:disabled+.radio-label {
        opacity: 0.5;
        cursor: not-allowed;
    }

    /* 现代化复选框样式 */
    .form-group input[type="checkbox"] {
        appearance: none;
        -webkit-appearance: none;
        width: 20px;
        height: 20px;
        border: 2px solid #d3d3d3;
        border-radius: 6px;
        position: relative;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        background: white;
        margin-right: 10px;
        flex-shrink: 0;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    }

    .form-group input[type="checkbox"]:hover {
        border-color: #0f0f0f;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        transform: translateY(-1px);
    }

    .form-group input[type="checkbox"]:focus {
        outline: none;
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
    }

    .form-group input[type="checkbox"]:checked {
        border-color: #0f0f0f;
        background: linear-gradient(135deg, #0f0f0f 0%, #2a2a2a 100%);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
    }

    .form-group input[type="checkbox"]:checked::after {
        content: '';
        position: absolute;
        top: 2px;
        left: 6px;
        width: 6px;
        height: 10px;
        border: solid white;
        border-width: 0 2px 2px 0;
        transform: rotate(45deg);
        opacity: 1;
        animation: checkmark 0.3s ease-in-out;
    }

    @keyframes checkmark {
        0% {
            opacity: 0;
            transform: rotate(45deg) scale(0);
        }

        50% {
            opacity: 1;
            transform: rotate(45deg) scale(1.2);
        }

        100% {
            opacity: 1;
            transform: rotate(45deg) scale(1);
        }
    }

    /* 复选框禁用状态 */
    .form-group input[type="checkbox"]:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        background: #f8f9fa;
        border-color: #e9ecef;
    }

    .form-group input[type="checkbox"]:disabled:hover {
        transform: none;
        box-shadow: none;
    }

    /* 美化的选择框样式 */
    .form-group select {
        appearance: none;
        -webkit-appearance: none;
        background: white;
        background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
        background-repeat: no-repeat;
        background-position: right 12px center;
        background-size: 16px;
        padding-right: 40px;
        border: 2px solid #dcdcdc;
        border-radius: 8px;
        transition: all 0.3s ease;
    }

    .form-group select:hover {
        border-color: #0f0f0f;
    }

    .form-group select:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
    }

    /* 美化的输入框样式 */
    .form-group input[type="text"],
    .form-group input[type="password"],
    .form-group input[type="number"],
    .form-group input[type="url"] {
        border: 2px solid #dcdcdc;
        border-radius: 8px;
        transition: all 0.3s ease;
        background: white;
    }

    .form-group input[type="text"]:hover,
    .form-group input[type="password"]:hover,
    .form-group input[type="number"]:hover,
    .form-group input[type="url"]:hover {
        border-color: #0f0f0f;
    }

    .form-group input[type="text"]:focus,
    .form-group input[type="password"]:focus,
    .form-group input[type="number"]:focus,
    .form-group input[type="url"]:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
    }

    /* 美化的按钮样式 */
    .btn {
        border: none;
        border-radius: 8px;
        padding: 12px 24px;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.3s ease;
        text-decoration: none;
        display: inline-block;
        text-align: center;
        position: relative;
        overflow: hidden;
    }

    .btn::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
        transition: left 0.5s;
    }

    .btn:hover::before {
        left: 100%;
    }

    .btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
    }

    /* 可搜索选择框样式 */
    .searchable-select-container {
        position: relative;
        width: 100%;
    }

    .searchable-select-input {
        width: 100%;
        padding: 10px 12px;
        border: 2px solid #dcdcdc;
        border-radius: 8px;
        background: white;
        font-size: 14px;
        transition: all 0.3s ease;
        cursor: pointer;
    }

    .searchable-select-input:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
        cursor: text;
    }

    .searchable-select-dropdown {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: white;
        border: 2px solid #dcdcdc;
        border-top: none;
        border-radius: 0 0 8px 8px;
        max-height: 200px;
        overflow-y: auto;
        z-index: 1000;
        display: none;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }

    .searchable-select-dropdown.show {
        display: block;
    }

    .searchable-select-option {
        padding: 10px 12px;
        cursor: pointer;
        border-bottom: 1px solid #f8f9fa;
        transition: background-color 0.2s ease;
        font-size: 14px;
    }

    .searchable-select-option:hover {
        background-color: #f8f9fa;
    }

    .searchable-select-option.highlighted {
        background-color: #0f0f0f;
        color: #f8f8f8;
    }

    .searchable-select-option:last-child {
        border-bottom: none;
    }

    .searchable-select-option[data-value=""] {
        color: #6c757d;
        font-style: italic;
    }

    /* 搜索框在下拉框显示时的样式 */
    .searchable-select-container.open .searchable-select-input {
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
        border-bottom: 1px solid #dcdcdc;
    }

    /* 滚动条美化 */
    .searchable-select-dropdown::-webkit-scrollbar {
        width: 6px;
    }

    .searchable-select-dropdown::-webkit-scrollbar-track {
        background: #f1f1f1;
    }

    .searchable-select-dropdown::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 3px;
    }

    .searchable-select-dropdown::-webkit-scrollbar-thumb:hover {
        background: #a1a1a1;
    }

    .btn-primary {
        background: linear-gradient(135deg, #0f0f0f 0%, #262626 100%);
        color: #f8f8f8;
        border: 1px solid #0f0f0f;
    }

    .btn-success {
        background: linear-gradient(135deg, #1f1f1f 0%, #3a3a3a 100%);
        color: #f8f8f8;
        border: 1px solid #1f1f1f;
    }

    .btn-secondary {
        background: #f2f2f2;
        color: #111111;
        border: 1px solid #d0d0d0;
    }

    .btn-warning {
        background: linear-gradient(135deg, #f5f5f5 0%, #dedede 100%);
        color: #111111;
        border: 1px solid #cfcfcf;
    }

    .btn-info {
        background: linear-gradient(135deg, #e9e9e9 0%, #d1d1d1 100%);
        color: #111111;
        border: 1px solid #c3c3c3;
    }

    .btn-danger {
        background: linear-gradient(135deg, #2a2a2a 0%, #0f0f0f 100%);
        color: #f8f8f8;
        border: 1px solid #0f0f0f;
    }

    /* OpenAI模型输入框样式 */
    .model-input-container {
        position: relative;
        display: flex;
        align-items: center;
    }

    .model-input,
    .model-select {
        flex: 1;
        border: 2px solid #dcdcdc;
        border-radius: 8px;
        padding: 10px 45px 10px 15px;
        font-size: 0.9rem;
        transition: all 0.3s ease;
        background: white;
    }

    .model-input:hover,
    .model-select:hover {
        border-color: #0f0f0f;
    }

    .model-input:focus,
    .model-select:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
    }

    .model-fetch-btn {
        position: absolute;
        right: 8px;
        top: 50%;
        transform: translateY(-50%);
        width: 32px;
        height: 32px;
        border: none;
        border-radius: 6px;
        background: #f8f9fa;
        cursor: pointer;
        font-size: 14px;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.3s ease;
        color: #6c757d;
    }

    .model-fetch-btn:hover {
        background: #0f0f0f;
        color: #f8f8f8;
        transform: translateY(-50%) scale(1.1);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
    }

    .model-fetch-btn:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        transform: translateY(-50%);
    }

    .model-fetch-btn.loading {
        animation: spin 1s linear infinite;
    }

    @keyframes spin {
        from {
            transform: translateY(-50%) rotate(0deg);
        }

        to {
            transform: translateY(-50%) rotate(360deg);
        }
    }

    /* 图片服务页面特定样式 */
    #image-service .form-group {
        margin-bottom: 15px;
    }

    #image-service .form-group label {
        font-weight: 500;
        color: #495057;
        margin-bottom: 5px;
        display: block;
    }

    #image-service .form-group input,
    #image-service .form-group select {
        width: 100%;
        padding: 8px 12px;
        border: 2px solid #dcdcdc;
        border-radius: 6px;
        font-size: 0.9em;
        transition: all 0.3s ease;
    }

    #image-service .form-group input:focus,
    #image-service .form-group select:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
    }

    #image-service .form-group small {
        color: #6c757d;
        font-size: 0.85em;
        line-height: 1.4;
    }

    /* 图片服务配置卡片悬停效果 */
    #image-service>.card>div>div {
        transition: all 0.3s ease;
    }

    #image-service>.card>div>div:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    }

    /* 图片获取方式选择框特殊样式 */
    #image-service label[onclick="toggleImageSourceConfig()"] {
        border: 2px solid #dcdcdc !important;
        border-radius: 12px !important;
        padding: 16px 20px !important;
        background: white !important;
        cursor: pointer !important;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
        position: relative;
        overflow: hidden;
    }

    #image-service label[onclick="toggleImageSourceConfig()"]:hover {
        border-color: #0f0f0f !important;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12) !important;
        transform: translateY(-2px) !important;
    }

    #image-service label[onclick="toggleImageSourceConfig()"]::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.08), transparent);
        transition: left 0.5s;
    }

    #image-service label[onclick="toggleImageSourceConfig()"]:hover::before {
        left: 100%;
    }

    /* 选中状态的图片获取方式 */
    #image-service label[onclick="toggleImageSourceConfig()"] input[type="checkbox"]:checked+div {
        color: #0f0f0f;
    }

    #image-service label[onclick="toggleImageSourceConfig()"] input[type="checkbox"]:checked {
        border-color: #0f0f0f;
        background: linear-gradient(135deg, #0f0f0f 0%, #2a2a2a 100%);
    }

    /* 复选框标签优化 */
    #image-service .form-group label[style*="display: flex"] {
        align-items: flex-start !important;
        gap: 12px !important;
        line-height: 1.5 !important;
    }

    #image-service .form-group label[style*="display: flex"] input[type="checkbox"] {
        margin-top: 2px;
    }

    /* Pollinations配置区域专用样式 */
    .pollinations-options-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 16px;
        margin-top: 15px;
    }

    .pollinations-option {
        background: rgba(255, 255, 255, 0.6);
        border: 1px solid rgba(0, 0, 0, 0.08);
        border-radius: 8px;
        padding: 12px 16px;
        transition: all 0.3s ease;
    }

    .pollinations-option:hover {
        background: rgba(17, 17, 17, 0.04);
        border-color: rgba(0, 0, 0, 0.2);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }

    .pollinations-checkbox-label {
        display: flex;
        align-items: flex-start;
        gap: 12px;
        cursor: pointer;
        width: 100%;
        margin: 0;
    }

    .pollinations-checkbox {
        margin-top: 2px;
        flex-shrink: 0;
    }

    .pollinations-option-text {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 4px;
        min-width: 0;
    }

    .pollinations-option-text strong {
        font-weight: 600;
        color: #111111;
        font-size: 0.95em;
        line-height: 1.3;
        display: block;
    }

    .pollinations-option-text small {
        color: #4a4a4a;
        font-size: 0.85em;
        line-height: 1.4;
        font-weight: 400;
        display: block;
        margin: 0;
    }

    /* 生成参数页面特定样式 */
    #generation-params .form-group {
        margin-bottom: 20px;
    }

    #generation-params .form-group label {
        font-weight: 600;
        color: #495057;
        margin-bottom: 8px;
        display: block;
    }

    #generation-params .form-group input,
    #generation-params .form-group select {
        width: 100%;
        padding: 10px 12px;
        border: 2px solid #dcdcdc;
        border-radius: 8px;
        font-size: 0.95em;
        transition: all 0.3s ease;
    }

    #generation-params .form-group input:focus,
    #generation-params .form-group select:focus {
        border-color: #0f0f0f;
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
        outline: none;
    }

    #generation-params .form-group small {
        color: #6c757d;
        font-size: 0.85em;
        line-height: 1.4;
        margin-top: 5px;
        display: block;
    }

    /* 输入框与滑块组合样式 */
    .input-with-range {
        display: flex;
        flex-direction: column;
        gap: 8px;
    }

    .input-with-range input[type="number"] {
        margin-bottom: 0 !important;
    }

    .input-with-range input[type="range"] {
        height: 6px;
        border-radius: 3px;
        background: #e5e5e5;
        outline: none;
        transition: all 0.3s ease;
    }

    .input-with-range input[type="range"]:hover {
        background: #dcdcdc;
    }

    .input-with-range input[type="range"]::-webkit-slider-thumb {
        appearance: none;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #0f0f0f;
        cursor: pointer;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        transition: all 0.3s ease;
    }

    .input-with-range input[type="range"]::-webkit-slider-thumb:hover {
        background: #2a2a2a;
        transform: scale(1.1);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }

    .input-with-range input[type="range"]::-moz-range-thumb {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #0f0f0f;
        cursor: pointer;
        border: none;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        transition: all 0.3s ease;
    }

    .input-with-range input[type="range"]::-moz-range-thumb:hover {
        background: #2a2a2a;
        transform: scale(1.1);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }

    /* 开关样式复选框 (用于主要的启用/禁用选项) */
    .toggle-switch {
        position: relative;
        display: inline-block;
        width: 50px;
        height: 24px;
        margin-right: 12px;
        flex-shrink: 0;
    }

    .toggle-switch input[type="checkbox"] {
        opacity: 0;
        width: 0;
        height: 0;
        position: absolute;
    }

    .toggle-slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #ccc;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        border-radius: 24px;
        box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
    }

    .toggle-slider:before {
        position: absolute;
        content: "";
        height: 18px;
        width: 18px;
        left: 3px;
        bottom: 3px;
        background-color: white;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        border-radius: 50%;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    }

    .toggle-switch input:checked+.toggle-slider {
        background: linear-gradient(135deg, #0f0f0f 0%, #2a2a2a 100%);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
    }

    .toggle-switch input:checked+.toggle-slider:before {
        transform: translateX(26px);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }

    .toggle-switch:hover .toggle-slider {
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);
    }

    .toggle-switch input:focus+.toggle-slider {
        box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
    }

    /* 开关样式的标签 */
    .toggle-label {
        display: flex;
        align-items: center;
        gap: 12px;
        font-weight: 500;
        color: #495057;
        cursor: pointer;
        user-select: none;
        transition: color 0.3s ease;
    }

    .toggle-label:hover {
        color: #0f0f0f;
    }

    /* 为主要的启用选项应用开关样式 */
    .main-toggle-option {
        padding: 20px;
        background: linear-gradient(135deg, #f9f9f9 0%, #ededed 100%);
        border-radius: 12px;
        border: 2px solid #dcdcdc;
        transition: all 0.3s ease;
        margin-bottom: 20px;
    }

    .main-toggle-option:hover {
        border-color: #0f0f0f;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
        .config-tabs {
            flex-direction: column;
            align-items: stretch;
        }

        .tab-btn {
            border-radius: 8px;
            margin-bottom: 5px;
        }

        .tab-btn.active {
            transform: none;
        }

        .grid {
            grid-template-columns: 1fr;
        }

        .model-fetch-btn {
            width: 28px;
            height: 28px;
            font-size: 12px;
        }

        /* 图片服务页面响应式 */
        #image-service .form-group {
            margin-bottom: 20px;
        }

        #image-service div[style*="grid-template-columns"] {
            grid-template-columns: 1fr !important;
        }

        /* 开关样式响应式 */
        .toggle-label {
            flex-direction: column;
            align-items: flex-start;
            gap: 8px;
        }

        .toggle-switch {
            align-self: flex-start;
        }

        .main-toggle-option {
            padding: 16px;
        }

        /* 复选框和单选框响应式 */
        .form-group input[type="checkbox"],
        .custom-radio input[type="radio"] {
            width: 18px;
            height: 18px;
        }

        .custom-radio input[type="radio"]:checked::after {
            width: 8px;
            height: 8px;
        }

        /* Pollinations配置响应式 */
        .pollinations-options-grid {
            grid-template-columns: 1fr !important;
            gap: 12px !important;
        }

        .pollinations-option {
            padding: 10px 12px;
        }

        .pollinations-checkbox-label {
            gap: 10px !important;
        }

        .pollinations-option-text strong {
            font-size: 0.9em;
        }

        .pollinations-option-text small {
            font-size: 0.8em;
        }

        /* 生成参数页面响应式 */
        #generation-params div[style*="grid-template-columns"] {
            grid-template-columns: 1fr !important;
        }

        #generation-params .form-group {
            margin-bottom: 25px;
        }

        .input-with-range {
            gap: 6px;
        }

        .input-with-range input[type="range"]::-webkit-slider-thumb {
            width: 16px;
            height: 16px;
        }

        .input-with-range input[type="range"]::-moz-range-thumb {
            width: 16px;
            height: 16px;
        }
    }
</style>
{% endblock %}

{% block extra_js %}
<script>
    // 全局变量
    let currentConfig = {};
    let modelRoleSettingsExpanded = false;
    let roleOpenAIModels = null;
    let roleOpenAIModelsPromise = null;
    let availableProviders = ['openai', 'anthropic', 'google', 'azure_openai', 'ollama', '302ai'];

    // 搜索选择框管理
    class SearchableSelect {
        constructor(containerId) {
            this.container = document.getElementById(containerId);
            this.input = this.container.querySelector('.searchable-select-input');
            this.dropdown = this.container.querySelector('.searchable-select-dropdown');
            this.options = [];
            this.originalPlaceholder = this.input.placeholder;
            this.selectedValue = '';

            this.init();
        }

        init() {
            // 点击输入框显示下拉框
            this.input.addEventListener('click', () => {
                this.show();
            });

            // 输入搜索
            this.input.addEventListener('input', (e) => {
                this.search(e.target.value);
            });

            // 按键处理
            this.input.addEventListener('keydown', (e) => {
                this.handleKeyDown(e);
            });

            // 点击外部关闭
            document.addEventListener('click', (e) => {
                if (!this.container.contains(e.target)) {
                    this.hide();
                }
            });

            // 输入框失去焦点时设置显示值
            this.input.addEventListener('blur', () => {
                setTimeout(() => {
                    if (!this.container.classList.contains('open')) {
                        this.updateDisplayValue();
                    }
                }, 100);
            });
        }

        setOptions(options) {
            this.options = options;
            this.updateDropdown(options);
        }

        updateDropdown(filteredOptions) {
            this.dropdown.innerHTML = '';

            if (filteredOptions.length === 0) {
                const noResultOption = document.createElement('div');
                noResultOption.className = 'searchable-select-option';
                noResultOption.textContent = '暂无匹配项';
                noResultOption.style.color = '#999';
                this.dropdown.appendChild(noResultOption);
                return;
            }

            filteredOptions.forEach((option, index) => {
                const optionElement = document.createElement('div');
                optionElement.className = 'searchable-select-option';
                optionElement.dataset.value = option.value;
                optionElement.textContent = option.label;

                if (index === 0) {
                    optionElement.classList.add('highlighted');
                }

                optionElement.addEventListener('click', () => {
                    this.selectOption(option);
                });

                this.dropdown.appendChild(optionElement);
            });
        }

        search(query) {
            const filteredOptions = this.options.filter(option =>
                option.label.toLowerCase().includes(query.toLowerCase()) ||
                option.value.toLowerCase().includes(query.toLowerCase())
            );
            this.updateDropdown(filteredOptions);

            if (!this.container.classList.contains('open')) {
                this.show();
            }
        }

        show() {
            this.container.classList.add('open');
            this.dropdown.classList.add('show');
            this.input.placeholder = '搜索模型...';
            if (this.selectedValue) {
                this.input.value = '';
            }
        }

        hide() {
            this.container.classList.remove('open');
            this.dropdown.classList.remove('show');
            this.updateDisplayValue();
        }

        selectOption(option) {
            this.selectedValue = option.value;
            this.input.value = option.label;

            // 更新对应的隐藏输入框的值
            const hiddenInput = this.container.parentNode.querySelector('.model-input');
            if (hiddenInput) {
                hiddenInput.value = option.value;
            }

            this.hide();
        }

        updateDisplayValue() {
            if (this.selectedValue) {
                const option = this.options.find(opt => opt.value === this.selectedValue);
                if (option) {
                    this.input.value = option.label;
                } else {
                    this.input.value = this.selectedValue;
                }
            } else {
                this.input.value = '';
                this.input.placeholder = this.originalPlaceholder;
            }
        }

        handleKeyDown(e) {
            const options = this.dropdown.querySelectorAll('.searchable-select-option');
            let highlighted = this.dropdown.querySelector('.highlighted');

            switch (e.key) {
                case 'ArrowDown':
                    e.preventDefault();
                    if (highlighted) {
                        highlighted.classList.remove('highlighted');
                        const next = highlighted.nextElementSibling;
                        if (next) {
                            next.classList.add('highlighted');
                        } else if (options.length > 0) {
                            options[0].classList.add('highlighted');
                        }
                    } else if (options.length > 0) {
                        options[0].classList.add('highlighted');
                    }
                    break;

                case 'ArrowUp':
                    e.preventDefault();
                    if (highlighted) {
                        highlighted.classList.remove('highlighted');
                        const prev = highlighted.previousElementSibling;
                        if (prev) {
                            prev.classList.add('highlighted');
                        } else if (options.length > 0) {
                            options[options.length - 1].classList.add('highlighted');
                        }
                    } else if (options.length > 0) {
                        options[options.length - 1].classList.add('highlighted');
                    }
                    break;

                case 'Enter':
                    e.preventDefault();
                    if (highlighted && highlighted.dataset.value !== undefined) {
                        const option = this.options.find(opt => opt.value === highlighted.dataset.value);
                        if (option) {
                            this.selectOption(option);
                        }
                    }
                    break;

                case 'Escape':
                    this.hide();
                    break;
            }
        }

        setValue(value) {
            this.selectedValue = value;
            const option = this.options.find(opt => opt.value === value);
            if (option) {
                this.input.value = option.label;
            } else {
                this.input.value = value;
            }

            // 更新对应的隐藏输入框的值
            const hiddenInput = this.container.parentNode.querySelector('.model-input');
            if (hiddenInput) {
                hiddenInput.value = value;
            }
        }
    }

    // 初始化搜索选择框实例
    let openaiModelSelect, ai302ModelSelect;

    // 初始化
    document.addEventListener('DOMContentLoaded', function () {
        // 初始化搜索选择框
        initSearchableSelects();
        // 加载初始配置
        loadAllConfigs();
        // 检查图片服务状态
        checkImageServiceStatus();
        // 初始化模型任务配置的provider切换监听
        initModelRoleProviderListeners();
    });

    // 初始化搜索选择框
    function initSearchableSelects() {
        // 初始化OpenAI模型搜索选择框
        if (document.getElementById('openai_model_container')) {
            openaiModelSelect = new SearchableSelect('openai_model_container');
        }

        // 初始化302AI模型搜索选择框
        if (document.getElementById('302ai_model_container')) {
            ai302ModelSelect = new SearchableSelect('302ai_model_container');
        }
    }

    // 标签页切换功能
    function switchTab(tabName) {
        // 隐藏所有标签页内容
        document.querySelectorAll('.tab-content').forEach(content => {
            content.style.display = 'none';
            content.classList.remove('active');
        });

        // 移除所有标签按钮的激活状态
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.classList.remove('active');
        });

        // 显示选中的标签页内容
        const targetTab = document.getElementById(tabName);
        if (targetTab) {
            targetTab.style.display = 'block';
            targetTab.classList.add('active');
        }

        // 激活选中的标签按钮
        const targetBtn = document.querySelector(`[data-tab="${tabName}"]`);
        if (targetBtn) {
            targetBtn.classList.add('active');
        }

        // 加载对应的配置数据
        loadTabConfig(tabName);
    }

    // 加载标签页配置数据
    async function loadTabConfig(tabName) {
        try {
            const categoryMap = {
                'ai-providers': 'ai_providers',
                'model-roles': 'model_roles',
                'generation-params': 'generation_params',
                'app-config': 'app_config',
                'image-service': 'image_service'
            };

            const category = categoryMap[tabName];
            if (!category) return;

            const response = await fetch(`/api/config/${category}`);
            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    populateTabForm(tabName, result.config);
                }
            }
        } catch (error) {
            console.error('加载配置失败:', error);
        }
    }

    // 填充表单数据
    function populateTabForm(tabName, config) {
        const tabElement = document.getElementById(tabName);
        if (!tabElement) return;

        // 填充输入框
        tabElement.querySelectorAll('input, select, textarea').forEach(input => {
            const name = input.name;
            if (config[name] !== undefined) {
                if (input.type === 'checkbox') {
                    input.checked = config[name];
                } else if (input.type === 'password') {
                    // 对于密码字段，如果有配置值且输入框为空，则显示配置值
                    if (!input.value && config[name]) {
                        input.value = config[name];
                    }
                    // 如果有配置值，更新placeholder为掩码显示
                    if (config[name]) {
                        input.placeholder = '••••••••';
                    }
                } else {
                    input.value = config[name];
                }
            }
        });

        // 如果是图片服务标签页，触发选项显示更新
        if (tabName === 'image-service') {
            setTimeout(() => {
                toggleImageServiceOptions();
            }, 100);
        }
    }

    // AI提供者测试功能
    async function testProvider(providerName) {
        showLoading(`正在测试 ${providerName} 提供者...`);

        try {
            // 从前端页面获取配置信息
            const card = document.querySelector(`[data-provider="${providerName}"]`);
            if (!card) {
                throw new Error('找不到提供者配置卡片');
            }

            const config = {};
            const inputs = card.querySelectorAll('input, select');
            inputs.forEach(input => {
                if (input.name && input.name !== 'default_provider') {
                    // 获取输入的值，不管是否为空
                    const value = input.value.trim();
                    if (value) {
                        config[input.name] = value;
                    }
                }
            });

            // 根据不同的提供者进行测试
            let testResult;
            switch (providerName) {
                case 'openai':
                    testResult = await testOpenAIProvider(config);
                    break;
                case 'anthropic':
                    testResult = await testAnthropicProvider(config);
                    break;
                case 'google':
                    testResult = await testGoogleProvider(config);
                    break;
                case 'azure_openai':
                    testResult = await testAzureOpenAIProvider(config);
                    break;
                case 'ollama':
                    testResult = await testOllamaProvider(config);
                    break;
                case '302ai':
                    testResult = await test302AIProvider(config);
                    break;
                default:
                    throw new Error(`不支持的提供者: ${providerName}`);
            }

            showTestResult(testResult, testResult.success);
        } catch (error) {
            showTestResult({ error: error.message }, false);
        }
    }

    // 测试 OpenAI 提供者（仅通过后端代理）
    async function testOpenAIProvider(config) {
        try {
            // 获取配置 - 使用前端页面填写的信息
            let apiKey = config.openai_api_key;
            let baseUrl = config.openai_base_url;
            let model = config.openai_model;

            // 如果前端没有填写API Key，尝试从后端获取
            if (!apiKey) {
                const configResponse = await fetch('/api/config/ai_providers');
                if (configResponse.ok) {
                    const configResult = await configResponse.json();
                    if (configResult.success && configResult.config.openai_api_key) {
                        apiKey = configResult.config.openai_api_key;
                    }
                }
            }

            // 如果仍然没有API Key，提示用户
            if (!apiKey) {
                throw new Error('请先配置 OpenAI API Key');
            }

            // 如果没有填写 Base URL，使用默认值
            if (!baseUrl) {
                baseUrl = 'https://api.openai.com/v1';
            }

            // 如果没有填写模型，使用默认值
            if (!model) {
                model = 'gpt-4o';
            }

            // 确保 Base URL 格式正确
            if (!baseUrl.endsWith('/v1')) {
                baseUrl = baseUrl.endsWith('/') ? baseUrl + 'v1' : baseUrl + '/v1';
            }

            // 只通过后端代理测试，避免CORS问题
            const proxyResponse = await fetch('/api/ai/providers/openai/test', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    base_url: baseUrl,
                    api_key: apiKey,
                    model: model
                })
            });

            if (!proxyResponse.ok) {
                // 尝试解析错误响应
                let errorMessage = `HTTP ${proxyResponse.status}: ${proxyResponse.statusText}`;
                try {
                    const errorData = await proxyResponse.json();
                    if (errorData.error) {
                        errorMessage = errorData.error;
                    } else if (errorData.detail) {
                        errorMessage = errorData.detail;
                    } else if (errorData.message) {
                        errorMessage = errorData.message;
                    }
                } catch (parseError) {
                    // 如果无法解析错误响应，使用默认错误信息
                }
                throw new Error(errorMessage);
            }

            const proxyResult = await proxyResponse.json();

            // 处理不同的响应格式
            // 后端可能返回 status: "success" 或 success: true
            if (proxyResult.status === 'success' || proxyResult.success === true) {
                // 标准化响应格式
                return {
                    success: true,
                    provider: proxyResult.provider || 'openai',
                    model: proxyResult.model || model,
                    response_preview: proxyResult.response_preview || '',
                    usage: proxyResult.usage || {
                        prompt_tokens: 0,
                        completion_tokens: 0,
                        total_tokens: 0
                    }
                };
            } else if (proxyResult.status === 'error' || proxyResult.success === false) {
                throw new Error(proxyResult.error || proxyResult.detail || proxyResult.message || '测试失败');
            } else {
                // 如果没有明确的状态字段，假设成功（因为HTTP状态码是200）
                return {
                    success: true,
                    provider: proxyResult.provider || 'openai',
                    model: proxyResult.model || model,
                    response_preview: proxyResult.response_preview || '',
                    usage: proxyResult.usage || {
                        prompt_tokens: 0,
                        completion_tokens: 0,
                        total_tokens: 0
                    }
                };
            }

        } catch (error) {
            return {
                success: false,
                error: error.message,
                detail: `OpenAI 测试失败: ${error.message}`
            };
        }
    }

    // 测试 Anthropic 提供者
    async function testAnthropicProvider(config) {
        try {
            let apiKey = config.anthropic_api_key;
            let model = config.anthropic_model || 'claude-3-5-sonnet-20241022';

            // 如果前端没有输入API Key，尝试从后端获取
            if (!apiKey) {
                const configResponse = await fetch('/api/config/ai_providers');
                if (configResponse.ok) {
                    const configResult = await configResponse.json();
                    if (configResult.success && configResult.config.anthropic_api_key) {
                        apiKey = configResult.config.anthropic_api_key;
                    }
                }
            }

            if (!apiKey) {
                throw new Error('请配置 Anthropic API Key');
            }

            // 调用 Anthropic API 进行测试
            const response = await fetch('https://api.anthropic.com/v1/messages', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'x-api-key': apiKey,
                    'anthropic-version': '2023-06-01'
                },
                body: JSON.stringify({
                    model: model,
                    messages: [
                        {
                            role: 'user',
                            content: 'Say "Hello, I am working!" in exactly 5 words.'
                        }
                    ]
                })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error?.message || `HTTP ${response.status}`);
            }

            const data = await response.json();

            return {
                success: true,
                provider: 'anthropic',
                model: model,
                response_preview: data.content[0].text,
                usage: {
                    prompt_tokens: data.usage?.input_tokens || 0,
                    completion_tokens: data.usage?.output_tokens || 0,
                    total_tokens: (data.usage?.input_tokens || 0) + (data.usage?.output_tokens || 0)
                }
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                detail: `Anthropic 测试失败: ${error.message}`
            };
        }
    }

    // 测试 Google 提供者
    async function testGoogleProvider(config) {
        try {
            let apiKey = config.google_api_key;
            let baseUrl = config.google_base_url || 'https://generativelanguage.googleapis.com';
            let model = config.google_model || 'gemini-1.5-flash';

            // 如果前端没有输入API Key或Base URL，尝试从后端获取
            if (!apiKey || !config.google_base_url) {
                const configResponse = await fetch('/api/config/ai_providers');
                if (configResponse.ok) {
                    const configResult = await configResponse.json();
                    if (configResult.success) {
                        if (!apiKey && configResult.config.google_api_key) {
                            apiKey = configResult.config.google_api_key;
                        }
                        if (!config.google_base_url && configResult.config.google_base_url) {
                            baseUrl = configResult.config.google_base_url;
                        }
                    }
                }
            }

            if (!apiKey) {
                throw new Error('请配置 Google API Key');
            }

            // 确保base URL格式正确
            if (!baseUrl.startsWith('http')) {
                baseUrl = 'https://' + baseUrl;
            }
            baseUrl = baseUrl.replace(/\/$/, ''); // 移除末尾的斜杠

            // 调用 Google Gemini API 进行测试
            const response = await fetch(`${baseUrl}/v1beta/models/${model}:generateContent?key=${apiKey}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    contents: [
                        {
                            parts: [
                                {
                                    text: 'Say "Hello, I am working!" in exactly 5 words.'
                                }
                            ]
                        }
                    ],
                    generationConfig: {
                        maxOutputTokens: 1000,
                        temperature: 0
                    }
                })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error?.message || `HTTP ${response.status}`);
            }

            const data = await response.json();

            // 检查响应数据结构
            if (!data.candidates || !data.candidates[0]) {
                throw new Error('API响应中没有candidates: ' + JSON.stringify(data));
            }

            const candidate = data.candidates[0];
            let responseText = '';

            // 检查不同的响应格式
            if (candidate.content && candidate.content.parts && candidate.content.parts[0] && candidate.content.parts[0].text) {
                responseText = candidate.content.parts[0].text;
            } else if (candidate.text) {
                responseText = candidate.text;
            } else {
                // 如果没有文本内容，可能是因为被安全过滤或其他原因
                const finishReason = candidate.finishReason || 'UNKNOWN';
                if (finishReason === 'MAX_TOKENS') {
                    responseText = '[响应被截断 - 令牌数量达到上限]';
                } else if (finishReason === 'SAFETY') {
                    responseText = '[响应被安全过滤器阻止]';
                } else {
                    responseText = `[无文本响应 - 结束原因: ${finishReason}]`;
                }
            }

            return {
                success: true,
                provider: 'google',
                model: model,
                response_preview: responseText,
                usage: {
                    prompt_tokens: data.usageMetadata?.promptTokenCount || 0,
                    completion_tokens: data.usageMetadata?.candidatesTokenCount || 0,
                    total_tokens: data.usageMetadata?.totalTokenCount || 0
                }
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                detail: `Google Gemini 测试失败: ${error.message}`
            };
        }
    }

    // 测试 Azure OpenAI 提供者
    async function testAzureOpenAIProvider(config) {
        try {
            let apiKey = config.azure_openai_api_key;
            let endpoint = config.azure_openai_endpoint;
            let deploymentName = config.azure_openai_deployment_name;
            let apiVersion = config.azure_openai_api_version || '2024-02-15-preview';

            // 如果前端没有输入，尝试从后端获取
            if (!apiKey || !endpoint || !deploymentName) {
                const configResponse = await fetch('/api/config/ai_providers');
                if (configResponse.ok) {
                    const configResult = await configResponse.json();
                    if (configResult.success) {
                        apiKey = apiKey || configResult.config.azure_openai_api_key;
                        endpoint = endpoint || configResult.config.azure_openai_endpoint;
                        deploymentName = deploymentName || configResult.config.azure_openai_deployment_name;
                    }
                }
            }

            if (!apiKey || !endpoint || !deploymentName) {
                throw new Error('请配置 Azure OpenAI 的所有必需参数');
            }

            // 确保 endpoint 格式正确
            if (!endpoint.endsWith('/')) {
                endpoint += '/';
            }

            // 调用 Azure OpenAI API 进行测试
            const url = `${endpoint}openai/deployments/${deploymentName}/chat/completions?api-version=${apiVersion}`;
            const response = await fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'api-key': apiKey
                },
                body: JSON.stringify({
                    messages: [
                        {
                            role: 'user',
                            content: 'Say "Hello, I am working!" in exactly 5 words.'
                        }
                    ],
                    temperature: 0
                })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error?.message || `HTTP ${response.status}`);
            }

            const data = await response.json();

            return {
                success: true,
                provider: 'azure_openai',
                model: deploymentName,
                response_preview: data.choices[0].message.content,
                usage: data.usage || {
                    prompt_tokens: 0,
                    completion_tokens: 0,
                    total_tokens: 0
                }
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                detail: `Azure OpenAI 测试失败: ${error.message}`
            };
        }
    }

    // 测试 Ollama 提供者
    async function testOllamaProvider(config) {
        try {
            let baseUrl = config.ollama_base_url || 'http://localhost:11434';
            let model = config.ollama_model || 'llama2';

            // 调用 Ollama API 进行测试
            const response = await fetch(`${baseUrl}/api/generate`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    model: model,
                    prompt: 'Say "Hello, I am working!" in exactly 5 words.',
                    stream: false,
                    options: {
                        num_predict: 20,
                        temperature: 0
                    }
                })
            });

            if (!response.ok) {
                const errorText = await response.text();
                throw new Error(errorText || `HTTP ${response.status}`);
            }

            const data = await response.json();

            return {
                success: true,
                provider: 'ollama',
                model: model,
                response_preview: data.response,
                usage: {
                    prompt_tokens: data.prompt_eval_count || 0,
                    completion_tokens: data.eval_count || 0,
                    total_tokens: (data.prompt_eval_count || 0) + (data.eval_count || 0)
                }
            };
        } catch (error) {
            // Ollama 可能未运行或无法连接
            if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
                return {
                    success: false,
                    error: 'Ollama 服务未运行或无法连接',
                    detail: `请确保 Ollama 正在运行并可以通过 ${config.ollama_base_url || 'http://localhost:11434'} 访问`
                };
            }
            return {
                success: false,
                error: error.message,
                detail: `Ollama 测试失败: ${error.message}`
            };
        }
    }

    // 测试 302.AI 提供者
    async function test302AIProvider(config) {
        try {
            let apiKey = config['302ai_api_key'];
            let baseUrl = config['302ai_base_url'] || 'https://api.302.ai/v1';
            let model = config['302ai_model'] || 'gpt-4o';

            // 如果前端没有填写API Key，尝试从后端获取
            if (!apiKey) {
                const configResponse = await fetch('/api/config/ai_providers');
                if (configResponse.ok) {
                    const configResult = await configResponse.json();
                    if (configResult.success && configResult.config['302ai_api_key']) {
                        apiKey = configResult.config['302ai_api_key'];
                    }
                }
            }

            // 如果仍然没有API Key，提示用户
            if (!apiKey) {
                throw new Error('请先配置 302.AI API Key，可通过 https://share.302.ai/5ml9vD 获取');
            }

            // 如果没有填写 Base URL，使用默认值
            if (!baseUrl) {
                baseUrl = 'https://api.302.ai/v1';
            }

            // 如果没有填写模型，使用默认值
            if (!model) {
                model = 'gpt-4o';
            }

            // 302.AI已经在隐藏字段中包含完整URL，无需额外处理

            // 调用 302.AI API 进行测试（兼容OpenAI格式）
            const response = await fetch(`${baseUrl}/chat/completions`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: model,
                    messages: [
                        {
                            role: 'user',
                            content: 'Say "Hello, I am working!" in exactly 5 words.'
                        }
                    ],
                    temperature: 0
                })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`);
            }

            const data = await response.json();

            return {
                success: true,
                provider: '302ai',
                model: model,
                response_preview: data.choices[0].message.content,
                usage: data.usage || {
                    prompt_tokens: 0,
                    completion_tokens: 0,
                    total_tokens: 0
                }
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                detail: `302.AI 测试失败: ${error.message}`
            };
        }
    }

    async function testCurrentProvider() {
        await testProvider('{{ current_provider }}');
    }

    function refreshProviders() {
        window.location.reload();
    }

    // 配置管理功能
    async function loadAllConfigs() {
        try {
            const response = await fetch('/api/config/all');
            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    currentConfig = result.config;
                    roleOpenAIModels = null;
                    roleOpenAIModelsPromise = null;
                    populateAllForms();
                }
            }
        } catch (error) {
            console.error('加载配置失败:', error);
        }
    }

    function populateAllForms() {
        // 填充AI提供者配置
        populateProviderForms();

        // 填充生成参数
        populateGenerationParams();

        // 填充应用配置
        populateAppConfig();

        // 填充图片服务配置
        populateImageServiceConfig();
    }

    function populateProviderForms() {
        document.querySelectorAll('.provider-config-card').forEach(card => {
            const provider = card.dataset.provider;
            const inputs = card.querySelectorAll('input, select');

            inputs.forEach(input => {
                const configKey = input.name;
                if (currentConfig[configKey]) {
                    if (input.type === 'checkbox') {
                        input.checked = currentConfig[configKey] === 'true';
                    } else if (input.type === 'password') {
                        // 对于密码字段，如果有配置值且输入框为空，则显示配置值
                        if (!input.value && currentConfig[configKey]) {
                            input.value = currentConfig[configKey];
                        }
                        // 如果有配置值，更新placeholder为掩码显示
                        if (currentConfig[configKey]) {
                            input.placeholder = '••••••••';
                        }
                    } else {
                        // 只有当输入框为空时才设置值，避免覆盖模板中已设置的值
                        if (!input.value && currentConfig[configKey]) {
                            input.value = currentConfig[configKey];
                        }
                    }
                }
            });
        });
    }

    // 切换模型任务配置显示
    function toggleModelRoleSettings() {
        const settingsDiv = document.getElementById('model-role-settings');
        const toggleBtn = document.getElementById('model-role-toggle-btn');

        if (settingsDiv && toggleBtn) {
            if (settingsDiv.style.display === 'none' || !settingsDiv.style.display) {
                settingsDiv.style.display = 'block';
                toggleBtn.textContent = '收起设置';
            } else {
                settingsDiv.style.display = 'none';
                toggleBtn.textContent = '展开设置';
            }
        }
    }

    // 存储每个role的SearchableSelect实例
    const roleModelSelects = {};

    // 初始化模型任务配置的provider切换监听器
    function initModelRoleProviderListeners() {
        const providerSelects = document.querySelectorAll('.model-role-provider');

        providerSelects.forEach(select => {
            // 初始化时检查provider
            updateModelRoleFetchButton(select);

            // 添加change事件监听
            select.addEventListener('change', function () {
                updateModelRoleFetchButton(this);
            });
        });
    }

    // 更新获取模型按钮的显示状态
    function updateModelRoleFetchButton(selectElement) {
        const modelField = selectElement.getAttribute('data-model-field');
        const fetchBtn = document.querySelector(`.openai-fetch-btn[data-model-field="${modelField}"]`);
        const searchableContainer = document.querySelector(`.role-model-searchable-select[data-model-field="${modelField}"]`);
        const modelInput = document.querySelector(`.role-model-input[data-model-field="${modelField}"]`);

        if (!fetchBtn) return;

        const selectedProvider = selectElement.value.toLowerCase();

        // 只有选择openai或302ai时显示按钮
        if (selectedProvider === 'openai' || selectedProvider === '302ai') {
            fetchBtn.style.display = 'flex';
        } else {
            fetchBtn.style.display = 'none';
            // 隐藏searchable select容器，显示普通输入框
            if (searchableContainer) searchableContainer.style.display = 'none';
            if (modelInput) modelInput.style.display = 'block';
        }
    }

    // 获取OpenAI模型列表
    async function fetchRoleOpenAIModels(buttonElement) {
        const modelField = buttonElement.getAttribute('data-model-field');
        const card = buttonElement.closest('.card');
        const providerSelect = card.querySelector('.model-role-provider');
        const searchableContainer = document.querySelector(`.role-model-searchable-select[data-model-field="${modelField}"]`);
        const modelInput = document.querySelector(`.role-model-input[data-model-field="${modelField}"]`);

        if (!providerSelect || !searchableContainer || !modelInput) return;

        const provider = providerSelect.value.toLowerCase();

        // 获取provider的配置信息
        const providerCard = document.querySelector(`[data-provider="${provider}"]`);
        if (!providerCard) {
            showNotification(`未找到 ${provider} 提供者的配置`, 'error');
            return;
        }

        try {
            buttonElement.disabled = true;
            buttonElement.classList.add('loading');
            buttonElement.innerHTML = '⏳';

            let models = null;

            if (provider === 'openai') {
                // 获取OpenAI配置
                const apiKeyInput = providerCard.querySelector('input[name="openai_api_key"]');
                const baseUrlInput = providerCard.querySelector('input[name="openai_base_url"]');

                const apiKey = apiKeyInput ? apiKeyInput.value.trim() : '';
                let baseUrl = baseUrlInput ? baseUrlInput.value.trim() : '';

                if (!apiKey) {
                    showNotification('请先配置OpenAI API Key', 'warning');
                    return;
                }

                if (!baseUrl) {
                    baseUrl = 'https://api.openai.com/v1';
                }

                models = await fetchOpenAIModels(baseUrl, apiKey);

            } else if (provider === '302ai') {
                // 获取302AI配置
                const apiKeyInput = providerCard.querySelector('input[name="302ai_api_key"]');
                const baseUrlInput = providerCard.querySelector('input[name="302ai_base_url"]');

                const apiKey = apiKeyInput ? apiKeyInput.value.trim() : '';
                let baseUrl = baseUrlInput ? baseUrlInput.value.trim() : '';

                if (!apiKey) {
                    showNotification('请先配置302.AI API Key', 'warning');
                    return;
                }

                if (!baseUrl) {
                    baseUrl = 'https://api.302.ai/v1';
                }

                models = await fetch302AIModelsList(baseUrl, apiKey);
            }

            if (!models || models.length === 0) {
                showNotification('未获取到可用模型', 'warning');
                return;
            }

            // 创建或更新SearchableSelect实例
            const selectId = `role-select-${modelField}`;

            // 如果还没有创建SearchableSelect实例，先设置容器ID
            if (!roleModelSelects[modelField]) {
                searchableContainer.id = selectId;
                roleModelSelects[modelField] = new SearchableSelect(selectId);
            }

            // 设置模型选项
            const modelOptions = models.map(model => ({
                value: model.id || model,
                label: model.id || model
            }));
            roleModelSelects[modelField].setOptions(modelOptions);

            // 隐藏普通输入框，显示searchable select
            modelInput.style.display = 'none';
            searchableContainer.style.display = 'block';

            // 如果当前有值，设置到searchable select
            if (modelInput.value) {
                roleModelSelects[modelField].selectedValue = modelInput.value;
                roleModelSelects[modelField].updateDisplayValue();
            }

            showNotification(`成功获取 ${models.length} 个模型`, 'success');

        } catch (error) {
            console.error('获取模型列表失败:', error);
            showNotification('获取模型列表失败: ' + error.message, 'error');
        } finally {
            buttonElement.disabled = false;
            buttonElement.classList.remove('loading');
            buttonElement.innerHTML = '列表';
        }
    }

    // 切换批量生成选项显示
    function toggleParallelGenerationOptions() {
        const enableCheckbox = document.getElementById('enable_parallel_generation');
        const optionsDiv = document.getElementById('parallel-generation-options');

        if (enableCheckbox && optionsDiv) {
            if (enableCheckbox.checked) {
                optionsDiv.style.display = 'block';
            } else {
                optionsDiv.style.display = 'none';
            }
        }
    }

    // 更新并行页数显示
    function updateParallelSlidesDisplay(value) {
        const displaySpan = document.getElementById('parallel_slides_display');
        if (displaySpan) {
            displaySpan.textContent = value + ' 页';
        }
    }

    function populateGenerationParams() {
        const tab = document.getElementById('generation-params');
        if (!tab) return;

        const inputs = tab.querySelectorAll('input, select');
        inputs.forEach(input => {
            const configKey = input.name;
            const configValue = currentConfig[configKey];
            if (configValue !== undefined && configValue !== null) {
                if (input.type === 'checkbox') {
                    const normalized = typeof configValue === 'string'
                        ? configValue.toLowerCase()
                        : configValue;
                    input.checked = normalized === true || normalized === 1 || normalized === 'true' || normalized === '1' || normalized === 'yes' || normalized === 'on';
                } else if (input.type === 'password') {
                    // 对于密码字段，如果有配置值且输入框为空，则显示配置值
                    if (!input.value && configValue) {
                        input.value = configValue;
                    }
                    // 如果有配置值，更新placeholder为掩码显示
                    if (configValue) {
                        input.placeholder = '••••••••';
                    }
                } else {
                    // 只有当输入框为空时才设置值，避免覆盖模板中已设置的值
                    if (!input.value && configValue !== '') {
                        input.value = configValue;
                    }
                }
            }
        });

        // 触发批量生成选项显示更新
        setTimeout(() => {
            toggleParallelGenerationOptions();
            const countInput = document.getElementById('parallel_slides_count');
            if (countInput) {
                updateParallelSlidesDisplay(countInput.value || countInput.getAttribute('value') || '0');
            }
        }, 100);
    }



    function populateAppConfig() {
        const tab = document.getElementById('app-config');
        if (!tab) return;

        const inputs = tab.querySelectorAll('input, select');
        inputs.forEach(input => {
            const configKey = input.name;
            if (currentConfig[configKey]) {
                if (input.type === 'checkbox') {
                    input.checked = currentConfig[configKey] === 'true';
                } else if (input.type === 'password') {
                    // 对于密码字段，如果有配置值且输入框为空，则显示配置值
                    if (!input.value && currentConfig[configKey]) {
                        input.value = currentConfig[configKey];
                    }
                    // 如果有配置值，更新placeholder为掩码显示
                    if (currentConfig[configKey]) {
                        input.placeholder = '••••••••';
                    }
                } else {
                    // 只有当输入框为空时才设置值，避免覆盖模板中已设置的值
                    if (!input.value && currentConfig[configKey]) {
                        input.value = currentConfig[configKey];
                    }
                }
            }
        });
    }

    function populateImageServiceConfig() {
        const tab = document.getElementById('image-service');
        if (!tab) return;

        const inputs = tab.querySelectorAll('input, select');
        inputs.forEach(input => {
            const configKey = input.name;
            if (currentConfig[configKey] !== undefined) {
                if (input.type === 'checkbox') {
                    input.checked = currentConfig[configKey] === 'true' || currentConfig[configKey] === true;
                } else if (input.type === 'password') {
                    // 对于密码字段，如果有配置值且输入框为空，则显示配置值
                    if (!input.value && currentConfig[configKey]) {
                        input.value = currentConfig[configKey];
                    }
                    // 如果有配置值，更新placeholder为掩码显示
                    if (currentConfig[configKey]) {
                        input.placeholder = '••••••••';
                    }
                } else {
                    // 只有当输入框为空时才设置值，避免覆盖模板中已设置的值
                    if (!input.value && currentConfig[configKey]) {
                        input.value = currentConfig[configKey];
                    }
                }
            }
        });

        // 触发图片服务选项显示更新
        setTimeout(() => {
            toggleImageServiceOptions();
        }, 100);
    }

    // 设置默认提供者
    async function setDefaultProvider(provider) {
        try {
            showLoading('正在设置默认提供者...');

            const response = await fetch('/api/config/default-provider', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ provider: provider })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification(`默认提供者已设置为 ${provider}，配置已实时生效`, 'success');

                    // 更新页面显示的当前提供者
                    updateCurrentProviderDisplay(provider);

                    // 可选：刷新提供者状态
                    setTimeout(() => {
                        refreshProviders();
                    }, 1000);
                } else {
                    showNotification('设置默认提供者失败: ' + (result.message || '未知错误'), 'error');
                }
            } else {
                showNotification('设置默认提供者失败', 'error');
            }

            closeTestModal();
        } catch (error) {
            showNotification('设置默认提供者失败: ' + error.message, 'error');
            closeTestModal();
        }
    }

    // 更新当前提供者显示
    function updateCurrentProviderDisplay(provider) {
        const currentProviderSpan = document.querySelector('.card p span');
        if (currentProviderSpan) {
            currentProviderSpan.textContent = provider;
        }
    }

    // 保存模型任务配置
    async function saveModelRoleConfig() {
        const tab = document.getElementById('model-roles');
        if (!tab) return;

        const config = {};
        tab.querySelectorAll('select, input').forEach(control => {
            if (!control.name) return;
            config[control.name] = control.value && typeof control.value === 'string' ? control.value.trim() : control.value;
        });

        try {
            // showLoading('正在保存模型任务配置...');
            const response = await fetch('/api/config/model_roles', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ config })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification('模型任务配置保存成功,已实时生效', 'success');
                    loadAllConfigs();
                } else {
                    const errorMsg = result.errors ? JSON.stringify(result.errors) : (result.message || '未知错误');
                    showNotification('模型任务配置保存失败: ' + errorMsg, 'error');
                }
            } else {
                let errorMsg = `HTTP ${response.status}: ${response.statusText}`;
                try {
                    const errorData = await response.json();
                    if (errorData.error) errorMsg = errorData.error;
                    else if (errorData.detail) errorMsg = errorData.detail;
                } catch (_) { }
                showNotification('模型任务配置保存失败: ' + errorMsg, 'error');
            }
        } catch (error) {
            console.error('保存模型任务配置失败:', error);
            showNotification('保存模型任务配置失败: ' + error.message, 'error');
        }
    }

    async function saveProviderConfig(provider) {
        const card = document.querySelector(`[data-provider="${provider}"]`);
        if (!card) return;

        const config = {};
        const inputs = card.querySelectorAll('input, select');

        inputs.forEach(input => {
            if (input.name && input.value) {
                // 跳过 default_provider radio 按钮，因为它通过专门的 API 处理
                if (input.name === 'default_provider') {
                    return;
                }
                config[input.name] = input.value;
            }
        });

        try {
            showLoading(`正在保存 ${provider} 配置...`);

            const response = await fetch('/api/config/ai_providers', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ config: config })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification(`${provider} 配置保存成功，已实时生效`, 'success');
                    // 重新加载配置
                    loadAllConfigs();
                } else {
                    // 正确处理错误消息
                    let errorMsg = '未知错误';
                    if (result.errors) {
                        if (typeof result.errors === 'string') {
                            errorMsg = result.errors;
                        } else if (Array.isArray(result.errors)) {
                            errorMsg = result.errors.join('; ');
                        } else if (typeof result.errors === 'object') {
                            // 处理对象形式的错误
                            const errorMessages = [];
                            for (const [key, value] of Object.entries(result.errors)) {
                                if (Array.isArray(value)) {
                                    errorMessages.push(`${key}: ${value.join(', ')}`);
                                } else {
                                    errorMessages.push(`${key}: ${value}`);
                                }
                            }
                            errorMsg = errorMessages.length > 0 ? errorMessages.join('; ') : JSON.stringify(result.errors);
                        } else {
                            errorMsg = String(result.errors);
                        }
                    } else if (result.message) {
                        errorMsg = result.message;
                    } else if (result.error) {
                        errorMsg = result.error;
                    } else if (result.detail) {
                        errorMsg = result.detail;
                    }
                    showNotification(`${provider} 配置保存失败: ${errorMsg}`, 'error');
                }
            } else {
                // 尝试解析错误响应
                let errorMsg = `HTTP ${response.status}: ${response.statusText}`;
                try {
                    const errorData = await response.json();
                    if (errorData.error) {
                        errorMsg = errorData.error;
                    } else if (errorData.detail) {
                        errorMsg = errorData.detail;
                    } else if (errorData.message) {
                        errorMsg = errorData.message;
                    }
                } catch (parseError) {
                    console.error('解析错误响应失败:', parseError);
                }
                showNotification(`${provider} 配置保存失败: ${errorMsg}`, 'error');
            }

            closeTestModal();
        } catch (error) {
            console.error('保存配置失败:', error);
            let errorMsg = error.message || '网络连接失败';
            if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
                errorMsg = '网络连接失败，请检查服务器状态';
            }
            showNotification('保存配置失败: ' + errorMsg, 'error');
            closeTestModal();
        }
    }

    // 保存生成参数
    async function saveGenerationParams() {
        const tab = document.getElementById('generation-params');
        if (!tab) return;

        const config = {};
        const inputs = tab.querySelectorAll('input, select');

        inputs.forEach(input => {
            if (input.name) {
                if (input.type === 'checkbox') {
                    config[input.name] = input.checked;
                } else if (input.value) {
                    config[input.name] = input.value;
                }
            }
        });

        try {
            const response = await fetch('/api/config/generation_params', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ config: config })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification('生成参数保存成功，已实时生效', 'success');
                    // 重新加载配置
                    loadAllConfigs();
                } else {
                    showNotification('生成参数保存失败: ' + (result.errors || '未知错误'), 'error');
                }
            } else {
                showNotification('生成参数保存失败', 'error');
            }
        } catch (error) {
            showNotification('保存失败: ' + error.message, 'error');
        }
    }



    // 保存应用配置
    async function saveAppConfig() {
        const tab = document.getElementById('app-config');
        if (!tab) return;

        const config = {};
        const inputs = tab.querySelectorAll('input, select');

        inputs.forEach(input => {
            if (input.name) {
                if (input.type === 'checkbox') {
                    config[input.name] = input.checked;
                } else if (input.value) {
                    config[input.name] = input.value;
                }
            }
        });

        try {
            const response = await fetch('/api/config/app_config', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ config: config })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification('应用配置保存成功，已实时生效', 'success');
                    // 重新加载配置
                    loadAllConfigs();
                } else {
                    showNotification('应用配置保存失败: ' + (result.errors || '未知错误'), 'error');
                }
            } else {
                showNotification('应用配置保存失败', 'error');
            }
        } catch (error) {
            showNotification('保存失败: ' + error.message, 'error');
        }
    }

    // 保存所有配置
    async function saveAllConfigs() {
        showLoading('正在保存所有配置...');

        try {
            // 收集所有配置
            const allConfig = {};

            // 收集AI提供者配置
            document.querySelectorAll('.provider-config-card').forEach(card => {
                const inputs = card.querySelectorAll('input, select');
                inputs.forEach(input => {
                    if (input.name && input.value) {
                        // 跳过 default_provider radio 按钮，因为它通过专门的 API 处理
                        if (input.name === 'default_provider') {
                            return;
                        }
                        allConfig[input.name] = input.value;
                    }
                });
            });

            // 收集其他配置
            ['generation-params', 'app-config'].forEach(tabId => {
                const tab = document.getElementById(tabId);
                if (tab) {
                    const inputs = tab.querySelectorAll('input, select');
                    inputs.forEach(input => {
                        if (input.name) {
                            if (input.type === 'checkbox') {
                                allConfig[input.name] = input.checked;
                            } else if (input.value) {
                                allConfig[input.name] = input.value;
                            }
                        }
                    });
                }
            });

            const response = await fetch('/api/config/all', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ config: allConfig })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification('所有配置保存成功', 'success');
                } else {
                    showNotification('配置保存失败: ' + (result.errors || '未知错误'), 'error');
                }
                closeTestModal();
            } else {
                showNotification('配置保存失败', 'error');
                closeTestModal();
            }
        } catch (error) {
            showNotification('保存失败: ' + error.message, 'error');
            closeTestModal();
        }
    }











    // 通知功能
    function showNotification(message, type = 'info') {
        // 创建通知元素
        const notification = document.createElement('div');
        notification.className = `notification notification-${type}`;
        notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        padding: 15px 20px;
        border-radius: 8px;
        color: white;
        font-weight: 600;
        z-index: 10000;
        max-width: 400px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        transform: translateX(100%);
        transition: transform 0.3s ease;
    `;

        // 设置背景颜色
        switch (type) {
            case 'success':
                notification.style.background = 'linear-gradient(135deg, #0f0f0f 0%, #2a2a2a 100%)';
                break;
            case 'error':
                notification.style.background = 'linear-gradient(135deg, #555555 0%, #1f1f1f 100%)';
                break;
            case 'warning':
                notification.style.background = 'linear-gradient(135deg, #666666 0%, #2f2f2f 100%)';
                break;
            default:
                notification.style.background = 'linear-gradient(135deg, #2a2a2a 0%, #0f0f0f 100%)';
        }

        notification.textContent = message;
        document.body.appendChild(notification);

        // 显示动画
        setTimeout(() => {
            notification.style.transform = 'translateX(0)';
        }, 100);

        // 自动隐藏
        setTimeout(() => {
            notification.style.transform = 'translateX(100%)';
            setTimeout(() => {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 300);
        }, 3000);
    }

    function showLoading(message) {
        document.getElementById('testResults').innerHTML = `
        <div style="text-align: center; padding: 20px;">
            <div style="font-size: 2em; margin-bottom: 10px;">⏳</div>
            <p>${message}</p>
        </div>
    `;
        document.getElementById('testModal').style.display = 'block';
    }

    function showTestResult(result, success) {
        const statusIcon = success ? '✅' : '❌';
        const statusColor = success ? '#0f0f0f' : '#555555';

        let content = `
        <div style="text-align: center; margin-bottom: 20px;">
            <div style="font-size: 3em; margin-bottom: 10px;">${statusIcon}</div>
            <h4 style="color: ${statusColor};">${success ? '测试成功' : '测试失败'}</h4>
        </div>
    `;

        if (success) {
            content += `
            <div style="background: #f8f9fa; padding: 20px; border-radius: 8px;">
                <p><strong>提供者:</strong> ${result.provider}</p>
                <p><strong>模型:</strong> ${result.model}</p>
                <p><strong>响应预览:</strong></p>
                <div style="background: white; padding: 15px; border-radius: 5px; margin-top: 10px; font-family: monospace; font-size: 0.9em;">
                    ${result.response_preview}
                </div>
                <p style="margin-top: 15px;"><strong>使用统计:</strong></p>
                <ul style="margin-left: 20px;">
                    <li>提示词令牌: ${result.usage.prompt_tokens}</li>
                    <li>完成令牌: ${result.usage.completion_tokens}</li>
                    <li>总令牌: ${result.usage.total_tokens}</li>
                </ul>
            </div>
        `;
        } else {
            content += `
            <div style="background: #f1f1f1; padding: 20px; border-radius: 8px; border-left: 4px solid #111111;">
                <p><strong>错误信息:</strong></p>
                <div style="background: rgba(0,0,0,0.1); padding: 10px; border-radius: 5px; font-family: monospace; font-size: 0.9em;">
                    ${result.detail || result.error || '未知错误'}
                </div>
            </div>
        `;
        }

        document.getElementById('testResults').innerHTML = content;
        document.getElementById('testModal').style.display = 'block';
    }

    function showAllTestResults(results) {
        let content = '<div style="margin-bottom: 20px;">';

        results.forEach(({ provider, result, success }) => {
            const statusIcon = success ? '✅' : '❌';
            const statusColor = success ? '#0f0f0f' : '#555555';

            content += `
            <div style="border: 1px solid #ecf0f1; border-radius: 8px; padding: 15px; margin-bottom: 15px;">
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
                    <strong>${provider}</strong>
                    <span style="color: ${statusColor};">${statusIcon} ${success ? '成功' : '失败'}</span>
                </div>
                ${success ?
                    `<p style="color: #7f8c8d; font-size: 0.9em;">模型: ${result.model} | 响应: ${result.response_preview.substring(0, 50)}...</p>` :
                    `<p style="color: #555555; font-size: 0.9em;">错误: ${result.detail || result.error}</p>`
                }
            </div>
        `;
        });

        content += '</div>';

        document.getElementById('testResults').innerHTML = content;
        document.getElementById('testModal').style.display = 'block';
    }

    function closeTestModal() {
        document.getElementById('testModal').style.display = 'none';
    }

    // Close modal when clicking outside
    document.getElementById('testModal').addEventListener('click', function (e) {
        if (e.target === this) {
            closeTestModal();
        }
    });

    // 图片服务相关功能
    async function checkImageServiceStatus() {
        try {
            const response = await fetch('/api/image/status');
            if (response.ok) {
                const result = await response.json();
                updateImageServiceStatus(result);
            } else {
                updateImageServiceStatus({
                    status: 'error',
                    available_providers: [],
                    message: '无法连接到图片服务'
                });
            }
        } catch (error) {
            updateImageServiceStatus({
                status: 'error',
                available_providers: [],
                message: '检查图片服务状态失败: ' + error.message
            });
        }
    }

    function updateImageServiceStatus(status) {
        const statusElement = document.getElementById('image-service-status');
        const providersElement = document.getElementById('available-image-providers');

        if (statusElement) {
            if (status.status === 'ok' && status.available_providers.length > 0) {
                statusElement.textContent = '✅ 正常运行';
                statusElement.style.background = '#0f0f0f';
            } else {
                statusElement.textContent = '❌ 服务异常';
                statusElement.style.background = '#555555';
            }
        }

        if (providersElement) {
            if (status.available_providers && status.available_providers.length > 0) {
                providersElement.textContent = status.available_providers.join(', ') + ` (${status.available_providers.length}个)`;
            } else {
                providersElement.textContent = '无可用提供者';
            }
        }
    }

    function showImageTestResult(result, success) {
        const statusIcon = success ? '✅' : '❌';
        const statusColor = success ? '#0f0f0f' : '#555555';

        let content = `
        <div style="text-align: center; margin-bottom: 20px;">
            <div style="font-size: 3em; margin-bottom: 10px;">${statusIcon}</div>
            <h4 style="color: ${statusColor};">${success ? '图片服务测试成功' : '图片服务测试失败'}</h4>
        </div>
    `;

        if (success) {
            content += `
            <div style="background: #f8f9fa; padding: 20px; border-radius: 8px;">
                <p><strong>测试结果:</strong></p>
                <ul style="margin-left: 20px;">
        `;

            if (result.providers) {
                Object.entries(result.providers).forEach(([provider, status]) => {
                    const icon = status.available ? '✅' : '❌';
                    content += `<li>${icon} ${provider}: ${status.message}</li>`;
                });
            }

            content += `
                </ul>
                <p style="margin-top: 15px;"><strong>缓存信息:</strong></p>
                <ul style="margin-left: 20px;">
                    <li>缓存目录: ${result.cache_info?.directory || 'temp/images_cache'}</li>
                    <li>缓存大小: ${result.cache_info?.size || '0 MB'}</li>
                    <li>文件数量: ${result.cache_info?.file_count || 0}</li>
                </ul>
            </div>
        `;
        } else {
            content += `
            <div style="background: #f1f1f1; padding: 20px; border-radius: 8px; border-left: 4px solid #111111;">
                <p><strong>错误信息:</strong></p>
                <div style="background: rgba(0,0,0,0.1); padding: 10px; border-radius: 5px; font-family: monospace; font-size: 0.9em;">
                    ${result.detail || result.error || '未知错误'}
                </div>
            </div>
        `;
        }

        document.getElementById('testResults').innerHTML = content;
        document.getElementById('testModal').style.display = 'block';
    }


    async function saveImageServiceConfig() {
        const tab = document.getElementById('image-service');
        if (!tab) return;

        const config = {};
        const inputs = tab.querySelectorAll('input, select');

        inputs.forEach(input => {
            if (input.name) {
                if (input.type === 'checkbox') {
                    config[input.name] = input.checked;
                } else if (input.value) {
                    config[input.name] = input.value;
                }
            }
        });

        try {
            const response = await fetch('/api/config/image_service', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ config: config })
            });

            if (response.ok) {
                const result = await response.json();
                if (result.success) {
                    showNotification('图片服务配置保存成功，已实时生效', 'success');
                    // 重新检查图片服务状态
                    checkImageServiceStatus();
                    // 重新加载配置
                    loadAllConfigs();
                } else {
                    // 正确处理错误信息
                    let errorMessage = '未知错误';
                    if (result.errors) {
                        if (typeof result.errors === 'string') {
                            errorMessage = result.errors;
                        } else if (typeof result.errors === 'object') {
                            // 如果errors是对象，将其转换为可读的字符串
                            errorMessage = JSON.stringify(result.errors, null, 2);
                        }
                    } else if (result.message) {
                        errorMessage = result.message;
                    }
                    showNotification('图片服务配置保存失败: ' + errorMessage, 'error');
                }
            } else {
                // 尝试解析错误响应
                try {
                    const errorResult = await response.json();
                    let errorMessage = '请求失败';
                    if (errorResult.detail) {
                        errorMessage = errorResult.detail;
                    } else if (errorResult.message) {
                        errorMessage = errorResult.message;
                    }
                    showNotification('图片服务配置保存失败: ' + errorMessage, 'error');
                } catch (parseError) {
                    showNotification('图片服务配置保存失败: HTTP ' + response.status, 'error');
                }
            }
        } catch (error) {
            showNotification('保存失败: ' + error.message, 'error');
        }
    }

    // 图片服务选项控制函数
    function toggleImageServiceOptions() {
        const enableCheckbox = document.querySelector('input[name="enable_image_service"]');
        const optionsDiv = document.getElementById('image-service-options');

        if (enableCheckbox && optionsDiv) {
            if (enableCheckbox.checked) {
                optionsDiv.style.display = 'block';
                // 触发一次配置显示更新
                toggleImageSourceConfig();
            } else {
                optionsDiv.style.display = 'none';
            }
        }
    }

    function toggleImageSourceConfig() {
        const localCheckbox = document.querySelector('input[name="enable_local_images"]');
        const networkCheckbox = document.querySelector('input[name="enable_network_search"]');
        const aiCheckbox = document.querySelector('input[name="enable_ai_generation"]');

        const localConfig = document.getElementById('local-images-config');
        const networkConfig = document.getElementById('network-search-config');
        const aiConfig = document.getElementById('ai-generation-config');

        if (!localConfig || !networkConfig || !aiConfig) return;

        // 根据复选框状态显示/隐藏对应配置
        if (localCheckbox && localCheckbox.checked) {
            localConfig.style.display = 'block';
        } else {
            localConfig.style.display = 'none';
        }

        if (networkCheckbox && networkCheckbox.checked) {
            networkConfig.style.display = 'block';
        } else {
            networkConfig.style.display = 'none';
        }

        if (aiCheckbox && aiCheckbox.checked) {
            aiConfig.style.display = 'block';
            // 当AI生成配置显示时，也检查提供商特定配置
            toggleProviderSpecificConfig();
        } else {
            aiConfig.style.display = 'none';
        }
    }

    function toggleProviderSpecificConfig() {
        const providerSelect = document.querySelector('select[name="default_ai_image_provider"]');
        const pollinationsConfig = document.getElementById('pollinations-specific-config');

        if (!providerSelect || !pollinationsConfig) return;

        const selectedProvider = providerSelect.value;

        // 显示/隐藏Pollinations特定配置
        if (selectedProvider === 'pollinations') {
            pollinationsConfig.style.display = 'block';
        } else {
            pollinationsConfig.style.display = 'none';
        }
    }

    // 获取并显示OpenAI模型列表
    async function fetchAndShowModels() {
        const inputElement = document.getElementById('openai_model_input');
        const fetchButton = document.getElementById('openai_model_fetch_btn');
        const containerElement = document.getElementById('openai_model_container');

        if (!inputElement || !fetchButton || !openaiModelSelect) return;

        try {
            // 设置加载状态
            fetchButton.classList.add('loading');
            fetchButton.disabled = true;
            fetchButton.textContent = '⏳';

            // 获取Base URL - 只使用前端页面填写的信息
            const baseUrlInput = document.querySelector('input[name="openai_base_url"]');
            let baseUrl = baseUrlInput ? baseUrlInput.value.trim() : '';

            // 如果没有设置Base URL，使用默认值
            if (!baseUrl) {
                baseUrl = 'https://api.openai.com/v1';
            }

            // 确保Base URL以/v1结尾
            if (!baseUrl.endsWith('/v1')) {
                if (baseUrl.endsWith('/')) {
                    baseUrl += 'v1';
                } else {
                    baseUrl += '/v1';
                }
            }

            // 获取API Key - 优先使用前端页面填写的信息，如果没有则从后端获取
            const apiKeyInput = document.querySelector('input[name="openai_api_key"]');
            let apiKey = apiKeyInput ? apiKeyInput.value.trim() : '';

            // 如果前端没有填写API Key，尝试从后端获取
            if (!apiKey) {
                try {
                    const configResponse = await fetch('/api/config/ai_providers');
                    if (configResponse.ok) {
                        const configResult = await configResponse.json();
                        if (configResult.success && configResult.config.openai_api_key) {
                            apiKey = configResult.config.openai_api_key;
                        }
                    }
                } catch (error) {
                    console.error('获取后端配置失败:', error);
                }
            }

            if (!apiKey) {
                showNotification('请先配置 OpenAI API Key', 'warning');
                return;
            }

            // 获取模型列表
            const models = await fetchOpenAIModels(baseUrl, apiKey);

            if (models && models.length > 0) {
                // 转换为搜索选择框的选项格式
                const options = models.map(model => ({
                    value: model.id,
                    label: model.id
                }));

                // 保存当前输入框的值
                const currentValue = inputElement.value;

                // 设置搜索选择框的选项
                openaiModelSelect.setOptions(options);

                // 如果当前搜索选择框是隐藏的，显示它并隐藏输入框
                if (containerElement.style.display === 'none') {
                    containerElement.style.display = 'block';
                    inputElement.style.display = 'none';

                    // 如果有当前值，设置到搜索选择框中
                    if (currentValue) {
                        openaiModelSelect.setValue(currentValue);
                    }
                } else {
                    // 如果搜索选择框已经显示，切换回输入模式
                    containerElement.style.display = 'none';
                    inputElement.style.display = 'block';
                }

                showNotification(`成功获取到 ${models.length} 个模型，请选择一个模型`, 'success');
            } else {
                showNotification('未能获取到模型列表，请检查Base URL和API Key配置', 'warning');
            }

        } catch (error) {
            console.error('获取模型列表失败:', error);
            showNotification('获取模型列表失败: ' + error.message, 'error');
        } finally {
            // 恢复按钮状态
            fetchButton.classList.remove('loading');
            fetchButton.disabled = false;
            fetchButton.textContent = '列表';
        }
    }

    // 获取并显示302AI模型列表
    async function fetch302AIModels() {
        const inputElement = document.getElementById('302ai_model_input');
        const fetchButton = document.getElementById('302ai_model_fetch_btn');
        const containerElement = document.getElementById('302ai_model_container');

        if (!inputElement || !fetchButton || !ai302ModelSelect) return;

        try {
            // 设置加载状态
            fetchButton.classList.add('loading');
            fetchButton.disabled = true;
            fetchButton.textContent = '⏳';

            // 获取Base URL - 只使用前端页面填写的信息
            const baseUrlInput = document.querySelector('input[name="302ai_base_url"]');
            let baseUrl = baseUrlInput ? baseUrlInput.value.trim() : '';

            // 如果没有设置Base URL，使用默认值
            if (!baseUrl) {
                baseUrl = 'https://api.302.ai/v1';
            }

            // 302.AI已经在隐藏字段中包含完整URL，无需额外处理

            // 获取API Key - 优先使用前端页面填写的信息，如果没有则从后端获取
            const apiKeyInput = document.querySelector('input[name="302ai_api_key"]');
            let apiKey = apiKeyInput ? apiKeyInput.value.trim() : '';

            // 如果前端没有填写API Key，尝试从后端获取
            if (!apiKey) {
                try {
                    const configResponse = await fetch('/api/config/ai_providers');
                    if (configResponse.ok) {
                        const configResult = await configResponse.json();
                        if (configResult.success && configResult.config['302ai_api_key']) {
                            apiKey = configResult.config['302ai_api_key'];
                        }
                    }
                } catch (error) {
                    console.error('获取后端配置失败:', error);
                }
            }

            if (!apiKey) {
                showNotification('请先配置 302.AI API Key，可通过 https://share.302.ai/5ml9vD 获取', 'warning');
                return;
            }

            // 获取模型列表（使用302.AI的兼容OpenAI格式）
            const models = await fetch302AIModelsList(baseUrl, apiKey);

            if (models && models.length > 0) {
                // 转换为搜索选择框的选项格式
                const options = models.map(model => ({
                    value: model.id,
                    label: model.id
                }));

                // 保存当前输入框的值
                const currentValue = inputElement.value;

                // 设置搜索选择框的选项
                ai302ModelSelect.setOptions(options);

                // 如果当前搜索选择框是隐藏的，显示它并隐藏输入框
                if (containerElement.style.display === 'none') {
                    containerElement.style.display = 'block';
                    inputElement.style.display = 'none';

                    // 如果有当前值，设置到搜索选择框中
                    if (currentValue) {
                        ai302ModelSelect.setValue(currentValue);
                    }
                } else {
                    // 如果搜索选择框已经显示，切换回输入模式
                    containerElement.style.display = 'none';
                    inputElement.style.display = 'block';
                }

                showNotification(`成功获取到 ${models.length} 个302.AI模型，请选择一个模型`, 'success');
            } else {
                showNotification('未能获取到模型列表，请检查Base URL和API Key配置', 'warning');
            }

        } catch (error) {
            console.error('获取302.AI模型列表失败:', error);
            showNotification('获取模型列表失败: ' + error.message, 'error');
        } finally {
            // 恢复按钮状态
            fetchButton.classList.remove('loading');
            fetchButton.disabled = false;
            fetchButton.textContent = '列表';
        }
    }

    // 从302.AI API获取模型列表（兼容OpenAI格式）
    async function fetch302AIModelsList(baseUrl, apiKey) {
        try {
            // 直接调用302.AI的models端点（兼容OpenAI格式）
            const response = await fetch(`${baseUrl}/models`, {
                method: 'GET',
                headers: {
                    'Authorization': `Bearer ${apiKey}`,
                    'Content-Type': 'application/json'
                }
            });

            if (!response.ok) {
                // 尝试解析错误响应
                let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
                try {
                    const errorData = await response.json();
                    if (errorData.error && errorData.error.message) {
                        errorMessage = errorData.error.message;
                    } else if (errorData.error) {
                        errorMessage = errorData.error;
                    } else if (errorData.message) {
                        errorMessage = errorData.message;
                    }
                } catch (parseError) {
                    // 如果无法解析错误响应，使用默认错误信息
                }
                throw new Error(errorMessage);
            }

            const data = await response.json();

            // 处理302.AI的响应格式（兼容OpenAI格式）
            let models = null;

            // 检查各种可能的响应格式
            if (data.data && Array.isArray(data.data)) {
                // OpenAI 兼容格式
                models = data.data;
            } else if (Array.isArray(data)) {
                // 直接返回数组的情况
                models = data;
            }

            if (models) {
                // 过滤并排序模型列表，优先显示常用的聊天模型
                const sortedModels = models
                    .filter(model => model.id || model.name) // 确保有ID或name
                    .map(model => {
                        // 标准化模型对象
                        return {
                            id: model.id || model.name,
                            name: model.name || model.id
                        };
                    })
                    .sort((a, b) => {
                        // 优先级排序：gpt-4 > claude-3 > gpt-3.5 > 其他
                        const getPriority = (id) => {
                            if (id.includes('gpt-4')) return 4;
                            if (id.includes('claude-3')) return 3;
                            if (id.includes('gpt-3.5')) return 2;
                            return 1;
                        };

                        const priorityA = getPriority(a.id.toLowerCase());
                        const priorityB = getPriority(b.id.toLowerCase());

                        if (priorityA !== priorityB) {
                            return priorityB - priorityA; // 高优先级在前
                        }

                        return a.id.localeCompare(b.id); // 同优先级按字母排序
                    });

                return sortedModels;
            }

            return null;

        } catch (error) {
            console.error('从302.AI获取模型列表失败:', error);
            throw error;
        }
    }

    // 从OpenAI API获取模型列表（仅通过后端代理）
    async function fetchOpenAIModels(baseUrl, apiKey) {
        try {
            // 只通过后端代理请求，避免CORS问题
            const response = await fetch('/api/ai/providers/openai/models', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    base_url: baseUrl,
                    api_key: apiKey
                })
            });

            if (!response.ok) {
                // 尝试解析错误响应
                let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
                try {
                    const errorData = await response.json();
                    if (errorData.error) {
                        errorMessage = errorData.error;
                    } else if (errorData.detail) {
                        errorMessage = errorData.detail;
                    } else if (errorData.message) {
                        errorMessage = errorData.message;
                    }
                } catch (parseError) {
                    // 如果无法解析错误响应，使用默认错误信息
                }
                throw new Error(errorMessage);
            }

            const data = await response.json();

            // 处理不同的响应格式
            let models = null;

            // 检查各种可能的响应格式
            if (data.models && Array.isArray(data.models)) {
                models = data.models;
            } else if (data.data && Array.isArray(data.data)) {
                // 兼容 OpenAI 原始格式
                models = data.data;
            } else if (Array.isArray(data)) {
                // 直接返回数组的情况
                models = data;
            }

            if (models) {
                // 过滤并排序模型列表，优先显示常用的聊天模型
                const sortedModels = models
                    .filter(model => model.id || model.name) // 确保有ID或name
                    .map(model => {
                        // 标准化模型对象
                        return {
                            id: model.id || model.name,
                            name: model.name || model.id
                        };
                    })
                    .sort((a, b) => {
                        // 优先级排序：gpt-4 > gpt-3.5 > gemini > 其他
                        const getPriority = (id) => {
                            if (id.includes('gpt-4')) return 4;
                            if (id.includes('gpt-3.5')) return 3;
                            if (id.includes('gemini')) return 2;
                            return 1;
                        };

                        const priorityA = getPriority(a.id);
                        const priorityB = getPriority(b.id);

                        if (priorityA !== priorityB) {
                            return priorityB - priorityA; // 降序
                        }

                        return a.id.localeCompare(b.id); // 字母序
                    });

                return sortedModels;
            } else {
                throw new Error('后端代理返回的数据格式不正确，未找到模型数据');
            }

        } catch (error) {
            console.error('通过后端代理获取模型列表失败:', error);
            throw error;
        }
    }

    // 初始化OpenAI模型输入框状态
    function initOpenAIModelInput() {
        const inputElement = document.getElementById('openai_model_input');
        if (inputElement && !inputElement.value.trim()) {
            inputElement.placeholder = '选择模型...';
        }
    }

    // 页面加载时初始化图片服务选项显示
    document.addEventListener('DOMContentLoaded', function () {
        // 延迟执行以确保DOM完全加载
        setTimeout(() => {
            toggleImageServiceOptions();
            toggleParallelGenerationOptions();
            initOpenAIModelInput();
        }, 100);
    });
</script>
{% endblock %}